- added 'disconnect' functionality for base station

- made IP->adress of base station editable
- some cleanup
This commit is contained in:
Dorian Zedler 2019-03-29 23:42:56 +01:00
parent b089584981
commit eeb939ed26
12 changed files with 198 additions and 78 deletions

View file

@ -110,6 +110,8 @@ public slots:
private slots: private slots:
void readyRead(); void readyRead();
void socketStateChanged(QAbstractSocket::SocketState socketState);
}; };
extern BaseConn * pGlobalBaseConn; extern BaseConn * pGlobalBaseConn;

View file

@ -89,8 +89,11 @@ public slots:
Q_INVOKABLE QString readSetting(QString key); Q_INVOKABLE QString readSetting(QString key);
Q_INVOKABLE bool connectBaseStation(); Q_INVOKABLE bool connectBaseStation();
Q_INVOKABLE void disconnectBaseStation();
Q_INVOKABLE QString getBaseStationState(); Q_INVOKABLE QString getBaseStationState();
Q_INVOKABLE QVariant getBaseStationConnections(); Q_INVOKABLE QVariant getBaseStationConnections();
Q_INVOKABLE bool reloadBaseStationIpAdress();
}; };
#endif // CLIMBINGRACE_H #endif // CLIMBINGRACE_H

View file

@ -279,44 +279,6 @@ Popup {
} }
} }
/*-----Page to connect to extenstions like a startpad or buzzer-----*/
Component {
id: connect
Column {
id: connect_col
property string title: qsTr("Base Station")
property int delegateHeight: height * 0.18
spacing: options_stack.rowSpacing
ConnectionDelegate {
id: connect_base_del
text: "connect"
status: { "status": speedBackend.baseStationState }
connect: speedBackend.connectBaseStation
type: "baseStation"
width: parent.width
height: options_stack.delegateHeight
font.pixelSize: height * 0.6
}
NextPageDelegate {
id: baseStationConnections_del
text: qsTr("connected extentions")
width: parent.width
height: options_stack.delegateHeight
onClicked: {
options_stack.push(baseStationConnections)
}
}
}
}
/*-----Page to setup automatc start sequence-----*/ /*-----Page to setup automatc start sequence-----*/
Component { Component {
id: autostart id: autostart
@ -363,6 +325,8 @@ Popup {
enabled: ready_del.checked enabled: ready_del.checked
text: qsTr("delay (ms)") text: qsTr("delay (ms)")
inputHint: qsTr("time")
inputMethodHints: Qt.ImhFormattedNumbersOnly
inputText: autostart_col.loadSetting("ready_delay", ready_del) inputText: autostart_col.loadSetting("ready_delay", ready_del)
@ -386,7 +350,6 @@ Popup {
} }
} }
InputDelegate { InputDelegate {
id: at_marks_delay_del id: at_marks_delay_del
@ -394,6 +357,8 @@ Popup {
height: options_stack.delegateHeight height: options_stack.delegateHeight
text: qsTr("delay (ms)") text: qsTr("delay (ms)")
inputHint: qsTr("time")
inputMethodHints: Qt.ImhFormattedNumbersOnly
enabled: at_marks_del.checked enabled: at_marks_del.checked
@ -406,6 +371,84 @@ Popup {
} }
} }
/*-----Page to connect to extenstions like a startpad or buzzer-----*/
Component {
id: connect
Column {
id: connectCol
property string title: qsTr("Base Station")
spacing: options_stack.rowSpacing
function baseConnected(){
return speedBackend.baseStationState === "connected"
}
ConnectionDelegate {
id: connectToBaseDel
text: status.status === "connected" ? qsTr("disconnect"): status.status === "disconnected" ? qsTr("connect"):qsTr("connecting...")
status: { "status": speedBackend.baseStationState }
connect: speedBackend.connectBaseStation
disconnect: speedBackend.disconnectBaseStation
type: "baseStation"
width: parent.width
height: options_stack.delegateHeight
font.pixelSize: height * 0.6
}
InputDelegate {
id: baseStationIpDel
text: qsTr("IP-Adress")
inputHint: "IP"
inputText: speedBackend.readSetting("baseStationIpAdress")
inputTextFieldWidth: width * 0.7
onInputTextChanged: {
speedBackend.writeSetting("baseStationIpAdress", inputText)
speedBackend.reloadBaseStationIpAdress()
}
width: parent.width
height: !connectCol.baseConnected() ? options_stack.delegateHeight:0
visible: height > 5
Behavior on height {
NumberAnimation {
duration: 400
easing.type: Easing.Linear
}
}
}
NextPageDelegate {
id: baseStationConnectionsDel
text: qsTr("connected extensions")
width: parent.width
height: connectCol.baseConnected() ? options_stack.delegateHeight:0
visible: height > 5
onClicked: {
options_stack.push(baseStationConnections)
}
Behavior on height {
NumberAnimation {
duration: 400
easing.type: Easing.Linear
}
}
}
}
}
/*-----Page to view devices that core connected to the pase startion-----*/ /*-----Page to view devices that core connected to the pase startion-----*/
Component{ Component{
id: baseStationConnections id: baseStationConnections
@ -419,11 +462,12 @@ Popup {
model: speedBackend.baseStationConnections.length model: speedBackend.baseStationConnections.length
delegate: ConnectionDelegate { delegate: ConnectionDelegate {
opacity: 1
width: parent.width width: parent.width
height: options_stack.delegateHeight height: options_stack.delegateHeight
enabled: false
text: speedBackend.baseStationConnections[index]["name"] text: speedBackend.baseStationConnections[index]["name"]
status: {'status': speedBackend.baseStationConnections[index]["state"], 'progress': speedBackend.baseStationConnections[index]["progress"]} status: {'status': speedBackend.baseStationConnections[index]["state"], 'progress': speedBackend.baseStationConnections[index]["progress"]}
} }

View file

@ -3,20 +3,29 @@ import QtQuick.Controls 2.2
SmoothItemDelegate { SmoothItemDelegate {
id: control id: control
property var status property var status
property var connect property var connect
property var disconnect
property string type property string type
text: qsTr(type) text: qsTr(type)
enabled: status.status === "disconnected" enabled: (status.status === "disconnected" && control.connect !== undefined) || ( status.status === "connected" && control.disconnect !== undefined )
onClicked: { onClicked: {
if(status.status === "disconnected"){
connect() connect()
if(status.status !== "connected"){ if(status.status !== "connected"){
statusIndicator.color_override = "red" statusIndicator.color_override = "red"
shortDelay.start() shortDelay.start()
} }
} }
else {
disconnect()
}
}
Timer { Timer {
id: shortDelay id: shortDelay
@ -35,7 +44,7 @@ SmoothItemDelegate {
rightMargin: ( height / control.height / 2 ) * height rightMargin: ( height / control.height / 2 ) * height
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
height: parent.font.pixelSize * 0.8 height: control.height * 0.4
width: height width: height
Rectangle { Rectangle {

View file

@ -12,6 +12,7 @@ Image {
width: height width: height
onOpacityChanged: visible = true onOpacityChanged: visible = true
SequentialAnimation { SequentialAnimation {
//rotating animation //rotating animation
running: status === "connecting" running: status === "connecting"
@ -29,12 +30,14 @@ Image {
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
} }
} }
Behavior on rotation { Behavior on rotation {
NumberAnimation { NumberAnimation {
duration: 200 duration: 200
easing.type: Easing.OutQuad easing.type: Easing.OutQuad
} }
} }
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: 200 duration: 200

View file

@ -5,6 +5,11 @@ SmoothItemDelegate {
id: control id: control
property string inputText: "" property string inputText: ""
property string inputHint: ""
property int inputMethodHints: Qt.ImhNone
property int inputTextFieldWidth: control.width * 0.3
onInputTextChanged: { onInputTextChanged: {
textField.text = inputText textField.text = inputText
@ -13,7 +18,7 @@ SmoothItemDelegate {
text: qsTr("delay (ms)") text: qsTr("delay (ms)")
width: parent.width width: parent.width
rightPadding: textField.width * 1.2 rightPadding: textField.width + width * 0.02
height: parent.delegateHeight height: parent.delegateHeight
TextField { TextField {
@ -22,17 +27,15 @@ SmoothItemDelegate {
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.width * 0.3 width: control.inputTextFieldWidth
height: parent.height height: parent.height
focus: true focus: true
placeholderText: qsTr("time") placeholderText: control.inputHint
font.pixelSize: height * 0.4 font.pixelSize: height * 0.4
opacity: control.enabled ? 1:0.2 inputMethodHints: control.inputMethodHints
inputMethodHints: Qt.ImhFormattedNumbersOnly
palette.text: appTheme.style.textColor palette.text: appTheme.style.textColor

View file

@ -5,6 +5,8 @@ SmoothItemDelegate {
id: control id: control
text: "" text: ""
rightPadding: forwardImage.width * 1.1
Image { Image {
id: forwardImage id: forwardImage
source: appTheme.style.backIcon source: appTheme.style.backIcon

View file

@ -7,6 +7,8 @@ ItemDelegate {
font.pixelSize: options_stack.text_pixelSize font.pixelSize: options_stack.text_pixelSize
property color textColor: appTheme.style.textColor property color textColor: appTheme.style.textColor
opacity: enabled ? 1 : 0.2
contentItem: Text { contentItem: Text {
visible: false visible: false
} }
@ -27,12 +29,13 @@ ItemDelegate {
fontSizeMode: Text.Fit fontSizeMode: Text.Fit
font.pixelSize: control.height * 0.4 font.pixelSize: control.height * 0.4
minimumPixelSize: 0
} }
width: parent.width width: parent.width
background: Rectangle { background: Rectangle {
opacity: enabled ? 1 : 0.3
color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
radius: height * 0.3 radius: height * 0.3
@ -43,4 +46,10 @@ ItemDelegate {
} }
} }
} }
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
} }

View file

@ -209,7 +209,19 @@ Window {
} }
} }
scale: 0
height: !root.landscape()? parent.height*0.17:parent.width*0.17 height: !root.landscape()? parent.height*0.17:parent.width*0.17
Component.onCompleted: {
scale = 1
}
Behavior on scale {
NumberAnimation {
duration: 200
}
}
} }
} }
} }
@ -226,9 +238,9 @@ Window {
visible: false visible: false
} }
/*---------------------- // ----------------------------------
Start / Stop / Reset button // -- Start / Stop / Reset button ---
----------------------*/ // ----------------------------------
FancyButton { FancyButton {
id : startButt id : startButt

View file

@ -33,6 +33,8 @@ AppSettings::AppSettings(QObject* parent)
this->setDefaultSetting("theme", "Light"); this->setDefaultSetting("theme", "Light");
this->setDefaultSetting("baseStationIpAdress", "192.168.4.1");
pGlobalAppSettings = this; pGlobalAppSettings = this;
} }

View file

@ -11,6 +11,8 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent)
connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(gotError(QAbstractSocket::SocketError))); this, SLOT(gotError(QAbstractSocket::SocketError)));
connect(this->socket, &QAbstractSocket::stateChanged, this, &BaseConn::socketStateChanged);
this->nextConnectionId = 1; this->nextConnectionId = 1;
this->connections = QVariantList({}); this->connections = QVariantList({});
} }
@ -54,6 +56,9 @@ bool BaseConn::connectToHost() {
void BaseConn::closeConnection() void BaseConn::closeConnection()
{ {
this->connections = QVariantList({});
emit this->connectionsChanged();
qDebug() << "closing connection"; qDebug() << "closing connection";
switch (socket->state()) switch (socket->state())
{ {
@ -213,6 +218,26 @@ void BaseConn::setState(QString newState){
emit stateChanged(); emit stateChanged();
} }
void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) {
switch (socketState) {
case QAbstractSocket::UnconnectedState:
{
this->setState("disconnected");
break;
}
case QAbstractSocket::ConnectedState:
{
this->setState("connected");
break;
}
default:
{
qDebug() << "+ --- UNKNOWN SOCKET STATE: " << socketState;
break;
}
}
}
int BaseConn::getProgress() const int BaseConn::getProgress() const
{ {
return(connection_progress); return(connection_progress);
@ -223,13 +248,20 @@ bool BaseConn::refreshConnections() {
if(reply["status"] != 200){ if(reply["status"] != 200){
//handle Error!! //handle Error!!
if(reply["status"] == 910){
this->connections = QVariantList({});
return true;
}
qDebug() << "+ --- error refreshing connections: " << reply["status"]; qDebug() << "+ --- error refreshing connections: " << reply["status"];
return false; return false;
} }
QVariantList tmpConnections = reply["data"].toList(); QVariantList tmpConnections = reply["data"].toList();
if(this->connections != reply["data"].toList()){
this->connections = reply["data"].toList(); this->connections = reply["data"].toList();
emit this->connectionsChanged();
}
return true; return true;
@ -239,7 +271,7 @@ QVariant BaseConn::getConnections() {
return(connections); return(connections);
/* /*
"id": "id of the extention (int)", "id": "id of the extention (int)",
"type": "type of the extention (can be: 'STARTPAD', 'TOPPAP')", "type": "type of the extention (can be: 'STARTPAD', 'TOPPAD')",
"name": "name of the extention", "name": "name of the extention",
"ip": "ip-adress of he extention (string)", "ip": "ip-adress of he extention (string)",
"state": "state of the extention (can be: 'disconnected', 'connecting', 'connected')" "state": "state of the extention (can be: 'disconnected', 'connecting', 'connected')"

View file

@ -18,8 +18,9 @@ ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent)
this->appSettings = new AppSettings; this->appSettings = new AppSettings;
this->baseConn = new BaseConn; this->baseConn = new BaseConn;
this->baseConn->setIP("192.168.4.1"); this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress"));
connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::baseStationStateChanged); connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::baseStationStateChanged);
connect(this->baseConn, &BaseConn::connectionsChanged, this, &ClimbingRace::baseStationConnectionsChanged);
this->speedTimers.append( new SpeedTimer ); this->speedTimers.append( new SpeedTimer );
@ -195,14 +196,14 @@ int ClimbingRace::resetRace() {
// ------------------------- // -------------------------
void ClimbingRace::syncWithBaseStation() { void ClimbingRace::syncWithBaseStation() {
this->baseConn->refreshConnections();
if(this->baseConn->state != "connected"){ if(this->baseConn->state != "connected"){
this->baseStationSyncTimer->start(); this->baseStationSyncTimer->start();
return; return;
} }
this->baseConn->refreshConnections();
emit this->baseStationConnectionsChanged();
QVariantMap tmpReply = this->baseConn->sendCommand(2000); QVariantMap tmpReply = this->baseConn->sendCommand(2000);
if(tmpReply["status"] != 200){ if(tmpReply["status"] != 200){
@ -229,20 +230,6 @@ void ClimbingRace::syncWithBaseStation() {
speedTimers[0]->setState(SpeedTimer::STARTING); speedTimers[0]->setState(SpeedTimer::STARTING);
} }
// tmpReply = this->baseConn->sendCommand(2004);
// if(tmpReply["status"] != 200){
// //handle Error!!
// qDebug() << "+ --- getting next start action from basestation failed: " << tmpReply["status"];
// this->baseStationSyncTimer->start();
// return;
// }
// else {
// if(this->nextStartAction != tmpReply["data"].toInt()){
// this->nextStartAction = tmpReply["data"].toInt();
// this->nextStartActionChanged(this->nextStartAction);
// }
// }
tmpReply = this->baseConn->sendCommand(2005); tmpReply = this->baseConn->sendCommand(2005);
if(tmpReply["status"] != 200){ if(tmpReply["status"] != 200){
//handle error!! //handle error!!
@ -360,7 +347,6 @@ void ClimbingRace::playSoundsAndStartRace() {
bool ClimbingRace::playSound(QString path) { bool ClimbingRace::playSound(QString path) {
//connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
player->setMedia(QUrl(path)); player->setMedia(QUrl(path));
player->setVolume(50); player->setVolume(50);
player->play(); player->play();
@ -509,9 +495,14 @@ QString ClimbingRace::readSetting(QString key) {
} }
bool ClimbingRace::connectBaseStation() { bool ClimbingRace::connectBaseStation() {
this->reloadBaseStationIpAdress();
return this->baseConn->connectToHost(); return this->baseConn->connectToHost();
} }
void ClimbingRace::disconnectBaseStation() {
this->baseConn->closeConnection();
}
QString ClimbingRace::getBaseStationState() { QString ClimbingRace::getBaseStationState() {
return this->baseConn->getState(); return this->baseConn->getState();
} }
@ -519,3 +510,11 @@ QString ClimbingRace::getBaseStationState() {
QVariant ClimbingRace::getBaseStationConnections() { QVariant ClimbingRace::getBaseStationConnections() {
return baseConn->getConnections(); return baseConn->getConnections();
} }
bool ClimbingRace::reloadBaseStationIpAdress() {
if(this->baseConn->state == "disconnected"){
this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress"));
return true;
}
return false;
}