Commit 049f678b authored by Dorian Zedler's avatar Dorian Zedler

- update file structure

- the base statio firmware updater is now fully working
parent 496d2747
......@@ -12,6 +12,7 @@
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <string.h>
#include <QByteArray>
#include "headers/appsettings.h"
#include "headers/speedtimer.h"
......@@ -37,9 +38,11 @@ public:
//---general status values---//
// some meta data of the base
QString version;
QString firmwareVersion;
bool firmwareUpToDate;
double timeOffset;
// the current state
QString state;
// can be:
......@@ -90,32 +93,41 @@ signals:
void gotError(QString error);
void propertiesChanged();
public slots:
Q_INVOKABLE void connectToHost();
void connectToHost();
//function to connect to the base station
void connectionTimeout();
Q_INVOKABLE bool init();
Q_INVOKABLE void deInit();
bool init();
void deInit();
Q_INVOKABLE void closeConnection();
void closeConnection();
void gotError(QAbstractSocket::SocketError err);
// --- socket communication handling ---
Q_INVOKABLE QVariantMap sendCommand(int header, QJsonValue data = "");
QVariantMap sendCommand(int header, QJsonValue data = "", bool useTerminationKeys = true, int timeout = 3000);
// --- updater functions ---
bool updateTime();
bool updateFirmware();
bool isFirmwareUpToDate();
// --- helper functions ---
Q_INVOKABLE int writeRemoteSetting(QString key, QString value);
int writeRemoteSetting(QString key, QString value);
Q_INVOKABLE bool refreshConnections();
bool refreshConnections();
void setConnections(QVariantList connections);
// functions for the qml adapter
QString getIP() const;
void setIP(const QString &ipAdress);
......
......@@ -20,6 +20,7 @@ class ClimbingRace : public QObject
Q_PROPERTY(QVariant baseStationConnections READ getBaseStationConnections NOTIFY baseStationConnectionsChanged)
Q_PROPERTY(double nextStartActionDelayProgress READ getNextStartActionDelayProgress NOTIFY nextStartActionDelayProgressChanged)
Q_PROPERTY(int nextStartAction READ getNextStartAction NOTIFY nextStartActionChanged)
Q_PROPERTY(QVariantMap baseStationProperties READ getBaseStationProperties NOTIFY baseStationPropertiesChanged)
public:
explicit ClimbingRace(QObject *parent = nullptr);
......@@ -76,6 +77,7 @@ signals:
void timerTextChanged();
void baseStationStateChanged();
void baseStationConnectionsChanged();
void baseStationPropertiesChanged();
public slots:
Q_INVOKABLE int startRace();
......@@ -99,6 +101,10 @@ public slots:
Q_INVOKABLE void disconnectBaseStation();
Q_INVOKABLE QString getBaseStationState();
Q_INVOKABLE QVariant getBaseStationConnections();
Q_INVOKABLE QVariantMap getBaseStationProperties();
Q_INVOKABLE bool updateBasestationFirmware();
Q_INVOKABLE bool updateBasestationTime();
// athlete management
Q_INVOKABLE QVariant getAthletes();
......
......@@ -5,19 +5,37 @@ import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Templates 2.12 as T
import "../components"
Column {
id: control
property string title: qsTr("base station")
spacing: parentObj.rowSpacing
property string title: qsTr("base station")
property bool baseConnected: speedBackend.baseStationState === "connected"
property var parentObj
opacity: 0
function doFirmwareUpdate() {
doFirmwareUpdateTimer.start()
}
Timer {
id: doFirmwareUpdateTimer
interval: 10
repeat: false
running: false
onTriggered: {
busyDl.open()
var ret = speedBackend.updateBasestationFirmware()
busyDl.displayMessageAndClose(ret ? "OK":"error", ret ? "#6bd43b":"#e03b2f" )
}
}
ConnectionDelegate {
id: connectToBaseDel
text: status.status === "connected" ? qsTr("disconnect"): status.status === "disconnected" ? qsTr("connect"):qsTr("connecting...")
......@@ -154,64 +172,235 @@ Column {
Component {
id: baseStationConnectedOptionsComp
Column {
id: baseStationConnectedOptions
ScrollView{
contentHeight: baseStationConnectedOptions.childrenRect.height
contentWidth: -1
width: parentComp.width
height: control.height - baseStationOptionsLd.y
clip: true
opacity: 0 // opacity and scale are adjusted by baseStationOptionsLd
scale: 0.95
SmoothSliderDelegate {
id: baseStationVolumeDel
text: qsTr("volume")
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
width: parent.width
height: parentObj.delegateHeight
Column {
id: baseStationConnectedOptions
sliderValue: 0
width: parentComp.width
onSliderFinished: {
speedBackend.writeSetting("soundVolume", sliderValue)
}
SmoothSliderDelegate {
id: baseStationVolumeDel
text: qsTr("volume")
width: parent.width
height: parentObj.delegateHeight
sliderValue: 0
onSliderFinished: {
enabled = false
speedBackend.writeSetting("soundVolume", sliderValue)
enabled = true
}
Component.onCompleted: {
var val = speedBackend.readSetting("soundVolume")
console.log(val)
if(val !== "false"){
sliderValue = parseFloat(val)
Component.onCompleted: {
var val = speedBackend.readSetting("soundVolume")
if(val !== "false"){
sliderValue = parseFloat(val)
}
}
}
Behavior on height {
NumberAnimation {
duration: 400
easing.type: Easing.Linear
NextPageDelegate {
id: baseStationConnectionsDel
text: qsTr("connected extensions")
width: parent.width
height: parentObj.delegateHeight
visible: height > 5
onClicked: {
parentObj.push(baseStationConnections)
}
}
}
NextPageDelegate {
id: baseStationConnectionsDel
text: qsTr("connected extensions")
SmoothItemDelegate {
id: baseStationUpdateDel
width: parent.width
height: parentObj.delegateHeight
// 0: hidden 1: update firmware 2: sync time
property int mode: speedBackend.baseStationProperties["firmware"]["upToDate"] ?
(Math.abs(parseInt(speedBackend.baseStationProperties["timeOffset"])) > 10000 ? 2:0)
:1
visible: height > 5
width: parent.width
height: mode > 0 ? parentObj.delegateHeight:0
onClicked: {
parentObj.push(baseStationConnections)
visible: height > 5
text: mode === 2 ? qsTr("sync time"):qsTr("update firmware")
onClicked: {
if(mode === 1) {
control.doFirmwareUpdate()
}
else if(mode === 2){
busyDl.open()
var ret = speedBackend.updateBasestationTime()
busyDl.displayMessageAndClose(ret ? "OK":"error", ret ? "#6bd43b":"#e03b2f" )
}
}
}
Behavior on height {
NumberAnimation {
duration: 400
easing.type: Easing.Linear
Rectangle {
anchors.left: parent.left
width: parent.width
height: 1
color: appTheme.style.lineColor
}
Item {
anchors.left: parent.left
width: parent.width
height: parentObj.delegateHeight * 0.5
Label {
anchors {
top: parent.top
left: parent.left
}
width: parent.width * 0.5
height: parent.height * 0.5
verticalAlignment: Text.AlignTop
horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
font.pixelSize: height
minimumPixelSize: 1
color: appTheme.style.lineColor
text: "version: " + speedBackend.baseStationProperties["firmware"]["version"]
}
Label {
property var date: new Date(new Date().getTime() + parseInt(speedBackend.baseStationProperties["timeOffset"]))
anchors {
top: parent.top
right: parent.right
}
width: parent.width * 0.5
height: parent.height
verticalAlignment: Text.AlignTop
horizontalAlignment: Text.AlignRight
fontSizeMode: Text.Fit
minimumPixelSize: 1
font.pixelSize: height
color: appTheme.style.lineColor
text: date.toLocaleDateString() + "\n" + date.toLocaleTimeString()
}
}
}
}
}
Popup {
id: busyDl
property string message: ""
property color messageColor: "transparent"
x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2)
width: app.width
height: app.height
modal: true
dim: true
closePolicy: Dialog.NoAutoClose
function displayMessageAndClose(message, messageColor) {
busyDl.message = message
busyDl.messageColor = messageColor
closeDelayTimer.start()
}
Timer {
id: closeDelayTimer
interval: 1000
repeat: false
running: false
onTriggered: {
busyDl.close()
busyDl.message = ""
busyDl.messageColor = "transparent"
}
}
background: Item {
FancyBusyIndicator {
anchors.centerIn: parent
opacity: busyDl.message === "" ? 1:0
lineColor: "white"
Behavior on opacity { NumberAnimation { duration: 150 } }
}
Label {
anchors.centerIn: parent
width: parent.width * 0.5
height: parent.height * 0.5
opacity: busyDl.message === "" ? 0:1
color: busyDl.messageColor
text: busyDl.message
fontSizeMode: Text.Fit
font.pixelSize: height
minimumPixelSize: 1
font.bold: true
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
Behavior on opacity { NumberAnimation { duration: 150 } }
}
}
T.Overlay.modal: Rectangle {
id: modalRect
color: "#80404040"
Behavior on opacity { NumberAnimation { duration: 150 } }
}
}
}
......
......@@ -182,6 +182,7 @@ Popup {
SettingsStack {
id: options_stack
width: headlineUnderline.width
enabled: opacity !== 0 //disable when not visible
......@@ -192,6 +193,7 @@ Popup {
leftMargin: ( parent.width - headlineUnderline.width ) / 2
topMargin: headlineUnderline.anchors.topMargin * 0.95
bottom: parent.bottom
bottomMargin: anchors.topMargin
}
Behavior on opacity {
......
......@@ -10,7 +10,7 @@ import "../components"
StackView {
id: control
property int delegateHeight: height * 0.2
property int delegateHeight: height * 0.25
property int rowSpacing: height * 0.01
initialItem: settings
......
......@@ -16,7 +16,9 @@ Column {
property var parentObj
function updateSetting(key, val, del){
del.busy = true
speedBackend.writeSetting(key, val)
del.busy = false
}
function loadSetting(key, del){
......@@ -26,31 +28,37 @@ Column {
SmoothSwitchDelegate {
id: ready_del
property bool busy: false
width: parent.width
height: parentObj.delegateHeight
enabled: !busy
text: qsTr("say 'ready'")
checked: parent.loadSetting("ready_en", ready_del) === "true"
onCheckedChanged: {
parent.updateSetting("ready_en",checked, ready_del)
parent.updateSetting("ready_en", checked, ready_del)
}
}
InputDelegate {
id: ready_delay_del
property bool busy: false
width: parent.width
height: parentObj.delegateHeight
enabled: ready_del.checked
enabled: !busy && ready_del.checked
text: qsTr("delay (ms)")
inputHint: qsTr("time")
inputMethodHints: Qt.ImhFormattedNumbersOnly
inputText: control.loadSetting("ready_delay", ready_del)
inputText: control.loadSetting("ready_delay", ready_delay_del)
onInputFinished: {
control.updateSetting("ready_delay", inputText, ready_delay_del)
......@@ -60,9 +68,13 @@ Column {
SmoothSwitchDelegate {
id: at_marks_del
property bool busy: false
width: parent.width
height: parentObj.delegateHeight
enabled: !busy
text: qsTr("say 'at your marks'")
checked: control.loadSetting("at_marks_en", ready_del) === "true"
......@@ -75,6 +87,8 @@ Column {
InputDelegate {
id: at_marks_delay_del
property bool busy: false
width: parent.width
height: parentObj.delegateHeight
......@@ -82,7 +96,7 @@ Column {
inputHint: qsTr("time")
inputMethodHints: Qt.ImhFormattedNumbersOnly
enabled: at_marks_del.checked
enabled: !busy && at_marks_del.checked
inputText: control.loadSetting("at_marks_delay", at_marks_delay_del)
......
......@@ -5,7 +5,10 @@ import QtQuick.Controls.Styles 1.2
BusyIndicator {
id: control
property double animationSpeed: 0.5
property double animationSpeed: 1000
property double formFactor: 4.5
property color lineColor: "#21be2b"
contentItem: Item {
implicitWidth: 64
......@@ -14,54 +17,20 @@ BusyIndicator {
Item {
id: item
x: parent.width / 2 - 32
y: parent.height / 2 - 32
width: 64
height: 64
opacity: control.running ? 1 : 0
anchors.fill: parent
property int currentHeight: 0
onCurrentHeightChanged: {
}
Behavior on opacity {
OpacityAnimator {
duration: 250
}
}
SequentialAnimation {
running: control.running
loops: Animation.Infinite
running: true
NumberAnimation {
target: item
duration: 2000 * 1/control.animationSpeed
to: 1000
properties: "currentHeight"
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: item
duration: 2000 * 1/control.animationSpeed
to: 0
properties: "currentHeight"
easing.type: Easing.InOutQuad
property: "currentHeight"
from: 0
to: 800
duration: control.animationSpeed
}
}
......@@ -77,7 +46,7 @@ BusyIndicator {
Rectangle {
property double heightMultiplier: Math.abs( Math.sin(( (item.currentHeight + (index*20))*0.01) * (Math.PI/2) ) )
property double heightMultiplier: Math.abs( Math.sin( ( ((item.currentHeight/100) + (index*(control.formFactor/repeater.model)))) * (Math.PI/8) ) )
anchors.verticalCenter: parent.verticalCenter
......@@ -86,7 +55,8 @@ BusyIndicator {
radius: width * 0.5
color: "#21be2b"
color: control.lineColor
}
}
}
......
......@@ -426,7 +426,7 @@ Window {
cornerRadius: startButtBackground.radius
anchors.fill: startButtBackground
scale: 0.75
opacity: Math.pow( control.opacity, 100 )