From 70d3091db3e073c2f8ea6f0486bd028d67ff84ba Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 20 Jul 2021 02:39:01 +0200 Subject: [PATCH] app now shows lots of new values and has a nice grid layout --- devicehandler.cpp | 630 ++++++++++++++++++++++++++++++----- devicehandler.h | 122 +++++-- main.cpp | 2 +- qml.qrc | 5 +- qml/App.qml | 2 +- qml/BluetoothAlarmDialog.qml | 2 +- qml/BottomLine.qml | 2 +- qml/Connect.qml | 4 +- qml/GameButton.qml | 2 +- qml/GamePage.qml | 2 +- qml/GameSettings.qml | 2 +- qml/Livedata.qml | 208 ++++++++++++ qml/LivedataMotor.qml | 54 +++ qml/Measure.qml | 194 ----------- qml/RemoteControl.qml | 40 +++ qml/SplashScreen.qml | 2 +- qml/Stats.qml | 49 --- qml/StatsLabel.qml | 2 +- qml/TitleBar.qml | 4 +- qml/main.qml | 4 +- 20 files changed, 953 insertions(+), 379 deletions(-) create mode 100644 qml/Livedata.qml create mode 100644 qml/LivedataMotor.qml delete mode 100644 qml/Measure.qml create mode 100644 qml/RemoteControl.qml delete mode 100644 qml/Stats.qml diff --git a/devicehandler.cpp b/devicehandler.cpp index a04bbf3..91fb8ab 100644 --- a/devicehandler.cpp +++ b/devicehandler.cpp @@ -5,18 +5,32 @@ namespace { const QBluetoothUuid bobbycarServiceUuid{QUuid::fromString(QStringLiteral("0335e46c-f355-4ce6-8076-017de08cee98"))}; -const QBluetoothUuid frontLeftSpeedCharacUuid{QUuid::fromString(QStringLiteral("81287506-8985-4cea-9a58-92fc5ad2c570"))}; -const QBluetoothUuid frontRightSpeedCharacUuid{QUuid::fromString(QStringLiteral("2f326a23-a676-4f87-b5cb-37a8fd7fe466"))}; -const QBluetoothUuid backLeftSpeedCharacUuid{QUuid::fromString(QStringLiteral("a7f951c0-e984-460d-98ed-0d54c64092d5"))}; -const QBluetoothUuid backRightSpeedCharacUuid{QUuid::fromString(QStringLiteral("14efe73f-6e34-49b3-b2c7-b513f3f5aee2"))}; + +const QBluetoothUuid frontVoltageCharacUuid{QUuid::fromString(QStringLiteral("a48321ea-329f-4eab-a401-30e247211524"))}; +const QBluetoothUuid backVoltageCharacUuid{QUuid::fromString(QStringLiteral("4201def0-a264-43e6-946b-6b2d9612dfed"))}; + +const QBluetoothUuid frontTemperatureCharacUuid{QUuid::fromString(QStringLiteral("4799e23f-6448-4786-900b-b5c3f3c17a9c"))}; +const QBluetoothUuid backTemperatureCharacUuid{QUuid::fromString(QStringLiteral("3c32b7bb-8d9b-4055-8ea0-5b6764111024"))}; + +const QBluetoothUuid frontLeftErrorCharacUuid{QUuid::fromString(QStringLiteral("f84b3a9b-1b2c-4075-acbe-016a2166976c"))}; +const QBluetoothUuid frontRightErrorCharacUuid{QUuid::fromString(QStringLiteral("eed4b709-5a65-4a5b-8e07-512f9661533d"))}; +const QBluetoothUuid backLeftErrorCharacUuid{QUuid::fromString(QStringLiteral("89d143f5-9ae2-4f7e-9235-643a3a7e21df"))}; +const QBluetoothUuid backRightErrorCharacUuid{QUuid::fromString(QStringLiteral("0fb377f1-7527-4966-aaf0-8bd56f2ddd3f"))}; + +const QBluetoothUuid frontLeftSpeedCharacUuid{QUuid::fromString(QStringLiteral("c6f959e8-0ec3-4bdd-88ad-6ad993fc81e9"))}; +const QBluetoothUuid frontRightSpeedCharacUuid{QUuid::fromString(QStringLiteral("ce53f135-8f20-4b80-abb9-31da81d62716"))}; +const QBluetoothUuid backLeftSpeedCharacUuid{QUuid::fromString(QStringLiteral("9a1dd1fe-3f14-4af1-bc5e-3f70edcae54b"))}; +const QBluetoothUuid backRightSpeedCharacUuid{QUuid::fromString(QStringLiteral("7de1a823-682e-438f-9201-3a80c3911f1a"))}; + +const QBluetoothUuid frontLeftDcLinkCharacUuid{QUuid::fromString(QStringLiteral("f404416f-2a77-41c6-a35f-7d10ec38376d"))}; +const QBluetoothUuid frontRightDcLinkCharacUuid{QUuid::fromString(QStringLiteral("452dd012-3f12-428c-8746-40c6b6c73c40"))}; +const QBluetoothUuid backLeftDcLinkCharacUuid{QUuid::fromString(QStringLiteral("9dc455a3-718e-4d62-b0e7-1c0cb2a8bbd3"))}; +const QBluetoothUuid backRightDcLinkCharacUuid{QUuid::fromString(QStringLiteral("90a66506-1d78-4ba2-b074-e1153fbf5216"))}; } DeviceHandler::DeviceHandler(QObject *parent) : BluetoothBaseClass(parent), - m_foundBobbycarService(false), - m_measuring(false), - m_currentValue(0), - m_min(0), m_max(0), m_sum(0), m_avg(0), m_distance(0) + m_foundBobbycarService(false) { } @@ -85,27 +99,6 @@ void DeviceHandler::setDevice(DeviceInfo *device) } } -void DeviceHandler::startMeasurement() -{ - if (alive()) { - m_start = QDateTime::currentDateTime(); - m_min = 0; - m_max = 0; - m_avg = 0; - m_sum = 0; - m_distance = 0; - m_measuring = true; - m_measurements.clear(); - emit measuringChanged(); - } -} - -void DeviceHandler::stopMeasurement() -{ - m_measuring = false; - emit measuringChanged(); -} - void DeviceHandler::serviceDiscovered(const QBluetoothUuid &gatt) { if (gatt == bobbycarServiceUuid) { @@ -138,6 +131,48 @@ void DeviceHandler::serviceScanDone() } } +namespace { +void logAddr(const QBluetoothUuid &uuid) +{ + if (uuid == bobbycarServiceUuid) + qDebug() << "bobbycarServiceUuid"; + else if (uuid == frontVoltageCharacUuid) + qDebug() << "frontVoltageCharacUuid"; + else if (uuid == backVoltageCharacUuid) + qDebug() << "backVoltageCharacUuid"; + else if (uuid == frontTemperatureCharacUuid) + qDebug() << "frontTemperatureCharacUuid"; + else if (uuid == backTemperatureCharacUuid) + qDebug() << "backTemperatureCharacUuid"; + else if (uuid == frontLeftErrorCharacUuid) + qDebug() << "frontLeftErrorCharacUuid"; + else if (uuid == frontRightErrorCharacUuid) + qDebug() << "frontRightErrorCharacUuid"; + else if (uuid == backLeftErrorCharacUuid) + qDebug() << "backLeftErrorCharacUuid"; + else if (uuid == backRightErrorCharacUuid) + qDebug() << "backRightErrorCharacUuid"; + else if (uuid == frontLeftSpeedCharacUuid) + qDebug() << "frontLeftSpeedCharacUuid"; + else if (uuid == frontRightSpeedCharacUuid) + qDebug() << "frontRightSpeedCharacUuid"; + else if (uuid == backLeftSpeedCharacUuid) + qDebug() << "backLeftSpeedCharacUuid"; + else if (uuid == backRightSpeedCharacUuid) + qDebug() << "backRightSpeedCharacUuid"; + else if (uuid == frontLeftDcLinkCharacUuid) + qDebug() << "frontLeftDcLinkCharacUuid"; + else if (uuid == frontRightDcLinkCharacUuid) + qDebug() << "frontRightDcLinkCharacUuid"; + else if (uuid == backLeftDcLinkCharacUuid) + qDebug() << "backLeftDcLinkCharacUuid"; + else if (uuid == backRightDcLinkCharacUuid) + qDebug() << "backRightDcLinkCharacUuid"; + else + qDebug() << "unknown uuid" << uuid; +} +} + void DeviceHandler::serviceStateChanged(QLowEnergyService::ServiceState s) { switch (s) { @@ -148,15 +183,197 @@ void DeviceHandler::serviceStateChanged(QLowEnergyService::ServiceState s) { setInfo(tr("Service discovered.")); - const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontLeftSpeedCharacUuid); - if (!hrChar.isValid()) { - setError("Bobbycar Data not found."); + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontVoltageCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontVoltage = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontVoltage.isValid()) + m_service->writeDescriptor(m_notificationDescFrontVoltage, QByteArray::fromHex("0100")); + } + else + { + setError("frontVoltageCharacUuid not found."); break; } - m_notificationDesc = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); - if (m_notificationDesc.isValid()) - m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100")); + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backVoltageCharacUuid); hrChar.isValid()) + { + m_notificationDescBackVoltage = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackVoltage.isValid()) + m_service->writeDescriptor(m_notificationDescBackVoltage, QByteArray::fromHex("0100")); + } + else + { + setError("backVoltageCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontTemperatureCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontTemperature = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontTemperature.isValid()) + m_service->writeDescriptor(m_notificationDescFrontTemperature, QByteArray::fromHex("0100")); + } + else + { + setError("frontTemperatureCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backTemperatureCharacUuid); hrChar.isValid()) + { + m_notificationDescBackTemperature = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackTemperature.isValid()) + m_service->writeDescriptor(m_notificationDescBackTemperature, QByteArray::fromHex("0100")); + } + else + { + setError("backTemperatureCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontLeftErrorCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontLeftError = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontLeftError.isValid()) + m_service->writeDescriptor(m_notificationDescFrontLeftError, QByteArray::fromHex("0100")); + } + else + { + setError("frontLeftErrorCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontRightErrorCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontRightError = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontRightError.isValid()) + m_service->writeDescriptor(m_notificationDescFrontRightError, QByteArray::fromHex("0100")); + } + else + { + setError("frontRightErrorCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backLeftErrorCharacUuid); hrChar.isValid()) + { + m_notificationDescBackLeftError = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackLeftError.isValid()) + m_service->writeDescriptor(m_notificationDescBackLeftError, QByteArray::fromHex("0100")); + } + else + { + setError("backLeftErrorCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backRightErrorCharacUuid); hrChar.isValid()) + { + m_notificationDescBackRightError = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackRightError.isValid()) + m_service->writeDescriptor(m_notificationDescBackRightError, QByteArray::fromHex("0100")); + } + else + { + setError("backRightErrorCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontLeftSpeedCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontLeftSpeed = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontLeftSpeed.isValid()) + m_service->writeDescriptor(m_notificationDescFrontLeftSpeed, QByteArray::fromHex("0100")); + } + else + { + setError("frontLeftSpeedCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontRightSpeedCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontRightSpeed = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontRightSpeed.isValid()) + m_service->writeDescriptor(m_notificationDescFrontRightSpeed, QByteArray::fromHex("0100")); + } + else + { + setError("frontRightSpeedCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backLeftSpeedCharacUuid); hrChar.isValid()) + { + m_notificationDescBackLeftSpeed = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackLeftSpeed.isValid()) + m_service->writeDescriptor(m_notificationDescBackLeftSpeed, QByteArray::fromHex("0100")); + } + else + { + setError("backLeftSpeedCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backRightSpeedCharacUuid); hrChar.isValid()) + { + m_notificationDescBackRightSpeed = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackRightSpeed.isValid()) + m_service->writeDescriptor(m_notificationDescBackRightSpeed, QByteArray::fromHex("0100")); + } + else + { + setError("backRightSpeedCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontLeftDcLinkCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontLeftDcLink = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontLeftDcLink.isValid()) + m_service->writeDescriptor(m_notificationDescFrontLeftDcLink, QByteArray::fromHex("0100")); + } + else + { + setError("frontLeftDcLinkCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(frontRightDcLinkCharacUuid); hrChar.isValid()) + { + m_notificationDescFrontRightDcLink = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescFrontRightDcLink.isValid()) + m_service->writeDescriptor(m_notificationDescFrontRightDcLink, QByteArray::fromHex("0100")); + } + else + { + setError("frontRightDcLinkCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backLeftDcLinkCharacUuid); hrChar.isValid()) + { + m_notificationDescBackLeftDcLink = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackLeftDcLink.isValid()) + m_service->writeDescriptor(m_notificationDescBackLeftDcLink, QByteArray::fromHex("0100")); + } + else + { + setError("backLeftDcLinkCharacUuid not found."); + break; + } + + if (const QLowEnergyCharacteristic hrChar = m_service->characteristic(backRightDcLinkCharacUuid); hrChar.isValid()) + { + m_notificationDescBackRightDcLink = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (m_notificationDescBackRightDcLink.isValid()) + m_service->writeDescriptor(m_notificationDescBackRightDcLink, QByteArray::fromHex("0100")); + } + else + { + setError("backRightDcLinkCharacUuid not found."); + break; + } break; } @@ -170,25 +387,242 @@ void DeviceHandler::serviceStateChanged(QLowEnergyService::ServiceState s) void DeviceHandler::updateBobbycarValue(const QLowEnergyCharacteristic &c, const QByteArray &value) { - // ignore any other characteristic change -> shouldn't really happen though - if (c.uuid() != frontLeftSpeedCharacUuid) - return; + //qDebug() << "updateBobbycarValue"; + //logAddr(c.uuid()); - bool ok; - float val = value.toFloat(&ok); - if (ok) - addMeasurement(val); - else - qWarning() << "could not parse float" << value; + if (c.uuid() == frontVoltageCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontVoltage = val; + emit frontVoltageChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontVoltage" << value; + } + else if (c.uuid() == backVoltageCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backVoltage = val; + emit backVoltageChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backVoltage" << value; + } + else if (c.uuid() == frontTemperatureCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontTemperature = val; + emit frontTemperatureChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontTemperature" << value; + } + else if (c.uuid() == backTemperatureCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backTemperature = val; + emit backTemperatureChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backTemperature" << value; + } + else if (c.uuid() == frontLeftErrorCharacUuid) + { + bool ok; + uint8_t val = value.toShort(&ok); + if (ok) + { + m_frontLeftError = val; + emit frontLeftErrorChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontLeftError" << value; + } + else if (c.uuid() == frontRightErrorCharacUuid) + { + bool ok; + uint8_t val = value.toShort(&ok); + if (ok) + { + m_frontRightError = val; + emit frontRightErrorChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontRightError" << value; + } + else if (c.uuid() == backLeftErrorCharacUuid) + { + bool ok; + uint8_t val = value.toShort(&ok); + if (ok) + { + m_backLeftError = val; + emit backLeftErrorChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backLeftError" << value; + } + else if (c.uuid() == backRightErrorCharacUuid) + { + bool ok; + uint8_t val = value.toShort(&ok); + if (ok) + { + m_backRightError = val; + emit backRightErrorChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backRightError" << value; + } + else if (c.uuid() == frontLeftSpeedCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontLeftSpeed = val; + emit frontLeftSpeedChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontLeftSpeed" << value; + } + else if (c.uuid() == frontRightSpeedCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontRightSpeed = val; + emit frontRightSpeedChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontRightSpeed" << value; + } + else if (c.uuid() == backLeftSpeedCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backLeftSpeed = val; + emit backLeftSpeedChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backLeftSpeed" << value; + } + else if (c.uuid() == backRightSpeedCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backRightSpeed = val; + emit backRightSpeedChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backRightSpeed" << value; + } + else if (c.uuid() == frontLeftDcLinkCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontLeftDcLink = val; + emit frontLeftDcLinkChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontLeftDcLink" << value; + } + else if (c.uuid() == frontRightDcLinkCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_frontRightDcLink = val; + emit frontRightDcLinkChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse frontRightDcLink" << value; + } + else if (c.uuid() == backLeftDcLinkCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backLeftDcLink = val; + emit backLeftDcLinkChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backLeftDcLink" << value; + } + else if (c.uuid() == backRightDcLinkCharacUuid) + { + bool ok; + float val = value.toFloat(&ok); + if (ok) + { + m_backRightDcLink = val; + emit backRightDcLinkChanged(); + } + else if (!value.isEmpty()) + qWarning() << "could not parse backRightDcLink" << value; + } } void DeviceHandler::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value) { - if (d.isValid() && d == m_notificationDesc && value == QByteArray::fromHex("0000")) { - //disabled notifications -> assume disconnect intent - m_control->disconnectFromDevice(); - delete m_service; - m_service = nullptr; + qDebug() << "confirmedDescriptorWrite" << d.uuid() << value; + if (d.isValid() && value == QByteArray::fromHex("0000")) + { + if (d == m_notificationDescFrontVoltage) + m_notificationDescFrontVoltage = {}; + if (d == m_notificationDescBackVoltage) + m_notificationDescBackVoltage = {}; + if (d == m_notificationDescFrontTemperature) + m_notificationDescFrontTemperature = {}; + if (d == m_notificationDescBackTemperature) + m_notificationDescBackTemperature = {}; + if (d == m_notificationDescFrontLeftError) + m_notificationDescFrontLeftError = {}; + if (d == m_notificationDescFrontRightError) + m_notificationDescFrontRightError = {}; + if (d == m_notificationDescBackLeftError) + m_notificationDescBackLeftError = {}; + if (d == m_notificationDescBackRightError) + m_notificationDescBackRightError = {}; + if (d == m_notificationDescFrontLeftSpeed) + m_notificationDescFrontLeftSpeed = {}; + if (d == m_notificationDescFrontRightSpeed) + m_notificationDescFrontRightSpeed = {}; + if (d == m_notificationDescBackLeftSpeed) + m_notificationDescBackLeftSpeed = {}; + if (d == m_notificationDescBackRightSpeed) + m_notificationDescBackRightSpeed = {}; + if (d == m_notificationDescFrontLeftDcLink) + m_notificationDescFrontLeftDcLink = {}; + if (d == m_notificationDescFrontRightDcLink) + m_notificationDescFrontRightDcLink = {}; + if (d == m_notificationDescBackLeftDcLink) + m_notificationDescBackLeftDcLink = {}; + if (d == m_notificationDescBackRightDcLink) + m_notificationDescBackRightDcLink = {}; + + disconnectInternal(); } } @@ -197,21 +631,74 @@ void DeviceHandler::disconnectService() m_foundBobbycarService = false; //disable notifications - if (m_notificationDesc.isValid() && m_service - && m_notificationDesc.value() == QByteArray::fromHex("0100")) { - m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000")); - } else { - if (m_control) - m_control->disconnectFromDevice(); + if (m_service) + { + if (m_notificationDescFrontVoltage.isValid() && m_notificationDescFrontVoltage.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontVoltage, QByteArray::fromHex("0000")); + if (m_notificationDescBackVoltage.isValid() && m_notificationDescBackVoltage.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackVoltage, QByteArray::fromHex("0000")); + if (m_notificationDescFrontTemperature.isValid() && m_notificationDescFrontTemperature.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontTemperature, QByteArray::fromHex("0000")); + if (m_notificationDescBackTemperature.isValid() && m_notificationDescBackTemperature.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackTemperature, QByteArray::fromHex("0000")); + if (m_notificationDescFrontLeftError.isValid() && m_notificationDescFrontLeftError.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontLeftError, QByteArray::fromHex("0000")); + if (m_notificationDescFrontRightError.isValid() && m_notificationDescFrontRightError.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontRightError, QByteArray::fromHex("0000")); + if (m_notificationDescBackLeftError.isValid() && m_notificationDescBackLeftError.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackLeftError, QByteArray::fromHex("0000")); + if (m_notificationDescBackRightError.isValid() && m_notificationDescBackRightError.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackRightError, QByteArray::fromHex("0000")); + if (m_notificationDescFrontLeftSpeed.isValid() && m_notificationDescFrontLeftSpeed.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontLeftSpeed, QByteArray::fromHex("0000")); + if (m_notificationDescFrontRightSpeed.isValid() && m_notificationDescFrontRightSpeed.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontRightSpeed, QByteArray::fromHex("0000")); + if (m_notificationDescBackLeftSpeed.isValid() && m_notificationDescBackLeftSpeed.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackLeftSpeed, QByteArray::fromHex("0000")); + if (m_notificationDescBackRightSpeed.isValid() && m_notificationDescBackRightSpeed.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackRightSpeed, QByteArray::fromHex("0000")); + if (m_notificationDescFrontLeftDcLink.isValid() && m_notificationDescFrontLeftDcLink.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontLeftDcLink, QByteArray::fromHex("0000")); + if (m_notificationDescFrontRightDcLink.isValid() && m_notificationDescFrontRightDcLink.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescFrontRightDcLink, QByteArray::fromHex("0000")); + if (m_notificationDescBackLeftDcLink.isValid() && m_notificationDescBackLeftDcLink.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackLeftDcLink, QByteArray::fromHex("0000")); + if (m_notificationDescBackRightDcLink.isValid() && m_notificationDescBackRightDcLink.value() == QByteArray::fromHex("0100")) + m_service->writeDescriptor(m_notificationDescBackRightDcLink, QByteArray::fromHex("0000")); - delete m_service; - m_service = nullptr; + disconnectInternal(); } } -bool DeviceHandler::measuring() const +void DeviceHandler::disconnectInternal() { - return m_measuring; + if (!m_notificationDescFrontVoltage.isValid() && + !m_notificationDescBackVoltage.isValid() && + !m_notificationDescFrontTemperature.isValid() && + !m_notificationDescBackTemperature.isValid() && + !m_notificationDescFrontLeftError.isValid() && + !m_notificationDescFrontRightError.isValid() && + !m_notificationDescBackLeftError.isValid() && + !m_notificationDescBackRightError.isValid() && + !m_notificationDescFrontLeftSpeed.isValid() && + !m_notificationDescFrontRightSpeed.isValid() && + !m_notificationDescBackLeftSpeed.isValid() && + !m_notificationDescBackRightSpeed.isValid() && + !m_notificationDescFrontLeftDcLink.isValid() && + !m_notificationDescFrontRightDcLink.isValid() && + !m_notificationDescBackLeftDcLink.isValid() && + !m_notificationDescBackRightDcLink.isValid()) + { + //disabled notifications -> assume disconnect intent + if (m_control) + m_control->disconnectFromDevice(); + + if (m_service) + { + delete m_service; + m_service = nullptr; + } + } } bool DeviceHandler::alive() const @@ -221,28 +708,3 @@ bool DeviceHandler::alive() const return false; } - -int DeviceHandler::time() const -{ - return m_start.secsTo(m_stop); -} - -void DeviceHandler::addMeasurement(float value) -{ - m_currentValue = value; - - // If measuring and value is appropriate - if (m_measuring) { - - m_stop = QDateTime::currentDateTime(); - m_measurements << value; - - m_min = m_min == 0 ? value : qMin(value, m_min); - m_max = qMax(value, m_max); - m_sum += value; - m_avg = (double)m_sum / m_measurements.size(); - m_distance += value * 1000.f * 3600; - } - - emit statsChanged(); -} diff --git a/devicehandler.h b/devicehandler.h index 48d0266..c786ff7 100644 --- a/devicehandler.h +++ b/devicehandler.h @@ -15,16 +15,24 @@ class DeviceInfo; class DeviceHandler : public BluetoothBaseClass { Q_OBJECT - - Q_PROPERTY(bool measuring READ measuring NOTIFY measuringChanged) - Q_PROPERTY(bool alive READ alive NOTIFY aliveChanged) - Q_PROPERTY(float speed READ speed NOTIFY statsChanged) - Q_PROPERTY(float maxSpeed READ maxSpeed NOTIFY statsChanged) - Q_PROPERTY(float minSpeed READ minSpeed NOTIFY statsChanged) - Q_PROPERTY(float avgSpeed READ avgSpeed NOTIFY statsChanged) - Q_PROPERTY(int time READ time NOTIFY statsChanged) - Q_PROPERTY(float distance READ distance NOTIFY statsChanged) Q_PROPERTY(AddressType addressType READ addressType WRITE setAddressType) + Q_PROPERTY(bool alive READ alive NOTIFY aliveChanged) + Q_PROPERTY(float frontVoltage READ frontVoltage NOTIFY frontVoltageChanged); + Q_PROPERTY(float backVoltage READ backVoltage NOTIFY backVoltageChanged); + Q_PROPERTY(float frontTemperature READ frontTemperature NOTIFY frontTemperatureChanged); + Q_PROPERTY(float backTemperature READ backTemperature NOTIFY backTemperatureChanged); + Q_PROPERTY(int frontLeftError READ frontLeftError NOTIFY frontLeftErrorChanged); + Q_PROPERTY(int frontRightError READ frontRightError NOTIFY frontRightErrorChanged); + Q_PROPERTY(int backLeftError READ backLeftError NOTIFY backLeftErrorChanged); + Q_PROPERTY(int backRightError READ backRightError NOTIFY backRightErrorChanged); + Q_PROPERTY(float frontLeftSpeed READ frontLeftSpeed NOTIFY frontLeftSpeedChanged); + Q_PROPERTY(float frontRightSpeed READ frontRightSpeed NOTIFY frontRightSpeedChanged); + Q_PROPERTY(float backLeftSpeed READ backLeftSpeed NOTIFY backLeftSpeedChanged); + Q_PROPERTY(float backRightSpeed READ backRightSpeed NOTIFY backRightSpeedChanged); + Q_PROPERTY(float frontLeftDcLink READ frontLeftDcLink NOTIFY frontLeftDcLinkChanged); + Q_PROPERTY(float frontRightDcLink READ frontRightDcLink NOTIFY frontRightDcLinkChanged); + Q_PROPERTY(float backLeftDcLink READ backLeftDcLink NOTIFY backLeftDcLinkChanged); + Q_PROPERTY(float backRightDcLink READ backRightDcLink NOTIFY backRightDcLinkChanged); public: enum class AddressType { @@ -39,28 +47,51 @@ public: void setAddressType(AddressType type); AddressType addressType() const; - bool measuring() const; bool alive() const; - // Statistics - float speed() const { return m_currentValue; } - int time() const; - float avgSpeed() const { return m_avg; } - float maxSpeed() const { return m_max; } - float minSpeed() const { return m_min; } - float distance() const { return m_distance; } + float frontVoltage() const { return m_frontVoltage; } + float backVoltage() const { return m_backVoltage; } + float frontTemperature() const { return m_frontTemperature; } + float backTemperature() const { return m_backTemperature; } + int frontLeftError() const { return m_frontLeftError; } + int frontRightError() const { return m_frontRightError; } + int backLeftError() const { return m_backLeftError; } + int backRightError() const { return m_backRightError; } + float frontLeftSpeed() const { return m_frontLeftSpeed; } + float frontRightSpeed() const { return m_frontRightSpeed; } + float backLeftSpeed() const { return m_backLeftSpeed; } + float backRightSpeed() const { return m_backRightSpeed; } + float frontLeftDcLink() const { return m_frontLeftDcLink; } + float frontRightDcLink() const { return m_frontRightDcLink; } + float backLeftDcLink() const { return m_backLeftDcLink; } + float backRightDcLink() const { return m_backRightDcLink; } signals: - void measuringChanged(); void aliveChanged(); - void statsChanged(); + + void frontVoltageChanged(); + void backVoltageChanged(); + void frontTemperatureChanged(); + void backTemperatureChanged(); + void frontLeftErrorChanged(); + void frontRightErrorChanged(); + void backLeftErrorChanged(); + void backRightErrorChanged(); + void frontLeftSpeedChanged(); + void frontRightSpeedChanged(); + void backLeftSpeedChanged(); + void backRightSpeedChanged(); + void frontLeftDcLinkChanged(); + void frontRightDcLinkChanged(); + void backLeftDcLinkChanged(); + void backRightDcLinkChanged(); public slots: - void startMeasurement(); - void stopMeasurement(); void disconnectService(); private: + void disconnectInternal(); + //QLowEnergyController void serviceDiscovered(const QBluetoothUuid &); void serviceScanDone(); @@ -73,24 +104,45 @@ private: const QByteArray &value); private: - void addMeasurement(float value); - + QLowEnergyController::RemoteAddressType m_addressType = QLowEnergyController::PublicAddress; QLowEnergyController *m_control = nullptr; QLowEnergyService *m_service = nullptr; - QLowEnergyDescriptor m_notificationDesc; - DeviceInfo *m_currentDevice = nullptr; + QLowEnergyDescriptor m_notificationDescFrontVoltage; + QLowEnergyDescriptor m_notificationDescBackVoltage; + QLowEnergyDescriptor m_notificationDescFrontTemperature; + QLowEnergyDescriptor m_notificationDescBackTemperature; + QLowEnergyDescriptor m_notificationDescFrontLeftError; + QLowEnergyDescriptor m_notificationDescFrontRightError; + QLowEnergyDescriptor m_notificationDescBackLeftError; + QLowEnergyDescriptor m_notificationDescBackRightError; + QLowEnergyDescriptor m_notificationDescFrontLeftSpeed; + QLowEnergyDescriptor m_notificationDescFrontRightSpeed; + QLowEnergyDescriptor m_notificationDescBackLeftSpeed; + QLowEnergyDescriptor m_notificationDescBackRightSpeed; + QLowEnergyDescriptor m_notificationDescFrontLeftDcLink; + QLowEnergyDescriptor m_notificationDescFrontRightDcLink; + QLowEnergyDescriptor m_notificationDescBackLeftDcLink; + QLowEnergyDescriptor m_notificationDescBackRightDcLink; + DeviceInfo *m_currentDevice{}; - bool m_foundBobbycarService; - bool m_measuring; - float m_currentValue, m_min, m_max, m_sum; - float m_avg, m_distance; + bool m_foundBobbycarService{}; - // Statistics - QDateTime m_start; - QDateTime m_stop; - - QVector m_measurements; - QLowEnergyController::RemoteAddressType m_addressType = QLowEnergyController::PublicAddress; + float m_frontVoltage{}; + float m_backVoltage{}; + float m_frontTemperature{}; + float m_backTemperature{}; + uint8_t m_frontLeftError{}; + uint8_t m_frontRightError{}; + uint8_t m_backLeftError{}; + uint8_t m_backRightError{}; + float m_frontLeftSpeed{}; + float m_frontRightSpeed{}; + float m_backLeftSpeed{}; + float m_backRightSpeed; + float m_frontLeftDcLink{}; + float m_frontRightDcLink{}; + float m_backLeftDcLink{}; + float m_backRightDcLink{}; }; #endif // DEVICEHANDLER_H diff --git a/main.cpp b/main.cpp index 4112fe5..daec7b9 100644 --- a/main.cpp +++ b/main.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) { - QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); + //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); diff --git a/qml.qrc b/qml.qrc index bab9635..975919c 100644 --- a/qml.qrc +++ b/qml.qrc @@ -7,8 +7,9 @@ qml/App.qml qml/TitleBar.qml qml/Connect.qml - qml/Measure.qml - qml/Stats.qml + qml/Livedata.qml + qml/LivedataMotor.qml + qml/RemoteControl.qml qml/GameButton.qml qml/GamePage.qml qml/BottomLine.qml diff --git a/qml/App.qml b/qml/App.qml index e4da72c..ede998f 100644 --- a/qml/App.qml +++ b/qml/App.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 Item { id: app diff --git a/qml/BluetoothAlarmDialog.qml b/qml/BluetoothAlarmDialog.qml index 619739c..05f727b 100644 --- a/qml/BluetoothAlarmDialog.qml +++ b/qml/BluetoothAlarmDialog.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 Item { id: root diff --git a/qml/BottomLine.qml b/qml/BottomLine.qml index 20f338d..35673d8 100644 --- a/qml/BottomLine.qml +++ b/qml/BottomLine.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 Rectangle { anchors.horizontalCenter: parent.horizontalCenter diff --git a/qml/Connect.qml b/qml/Connect.qml index ff13f8d..5f9e802 100644 --- a/qml/Connect.qml +++ b/qml/Connect.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 import Shared 1.0 GamePage { @@ -57,7 +57,7 @@ GamePage { anchors.fill: parent onClicked: { deviceFinder.connectToService(modelData.deviceAddress); - app.showPage("Measure.qml") + app.showPage("Livedata.qml") } } diff --git a/qml/GameButton.qml b/qml/GameButton.qml index 4a5b618..980ecc7 100644 --- a/qml/GameButton.qml +++ b/qml/GameButton.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 import "." Rectangle { diff --git a/qml/GamePage.qml b/qml/GamePage.qml index e0afe4e..7d4678f 100644 --- a/qml/GamePage.qml +++ b/qml/GamePage.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 import "." Item { diff --git a/qml/GameSettings.qml b/qml/GameSettings.qml index 09e20fe..1c63f38 100644 --- a/qml/GameSettings.qml +++ b/qml/GameSettings.qml @@ -1,5 +1,5 @@ pragma Singleton -import QtQuick 2.5 +import QtQuick 2.15 Item { property int wHeight diff --git a/qml/Livedata.qml b/qml/Livedata.qml new file mode 100644 index 0000000..93353f9 --- /dev/null +++ b/qml/Livedata.qml @@ -0,0 +1,208 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +GamePage { + id: livedatePage + + errorMessage: deviceHandler.error + infoMessage: deviceHandler.info + + property real avgSpeed: (deviceHandler.frontLeftSpeed + deviceHandler.frontRightSpeed + deviceHandler.backLeftSpeed + deviceHandler.backRightSpeed) / 4 + property real avgVoltage: (deviceHandler.frontVoltage + deviceHandler.backVoltage) / 2 + property real totalCurrent: deviceHandler.frontLeftDcLink + deviceHandler.frontRightDcLink + deviceHandler.backLeftDcLink + deviceHandler.backRightDcLink + property real totalPower: totalCurrent * avgVoltage + + function close() + { + deviceHandler.disconnectService(); + app.prevPage(); + } + + Rectangle { + id: container + anchors.centerIn: parent + anchors.horizontalCenter: parent.horizontalCenter + width: Math.min(livedatePage.width, livedatePage.height-GameSettings.fieldHeight*4) - 2*GameSettings.fieldMargin + height: livedatePage.height-GameSettings.fieldHeight*4 + radius: GameSettings.buttonRadius + color: GameSettings.viewColor + + Flickable { + id: flickable + + anchors.fill: parent + //spacing: GameSettings.buttonRadius + + contentWidth: contentColumn.width + contentHeight: contentColumn.height + flickableDirection: Flickable.VerticalFlick + clip: true + + Column { + id: contentColumn + + Text { + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: GameSettings.hugeFontSize * 2 + color: GameSettings.textColor + text: Number(avgSpeed).toLocaleString(Qt.locale()) + 'km/h' + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: GameSettings.hugeFontSize * 2 + color: GameSettings.textColor + text: Number(totalCurrent).toLocaleString(Qt.locale()) + 'A' + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: GameSettings.hugeFontSize * 2 + color: GameSettings.textColor + text: Number(totalPower>1000?(totalPower/1000):totalPower).toLocaleString(Qt.locale()) + (totalPower > 1000 ? "kW" : "W") + } + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: "Front: " + Number(deviceHandler.frontVoltage).toLocaleString(Qt.locale()) + "V / " + Number(deviceHandler.frontTemperature).toLocaleString(Qt.locale()) + "°C" + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + Grid { + columns: 2 + spacing: 10 + + LivedataMotor { + width: (container.width/2)-10; + + error: deviceHandler.frontLeftError + speed: deviceHandler.frontLeftSpeed + dcLink: deviceHandler.frontLeftDcLink + voltage: deviceHandler.frontVoltage + } + + LivedataMotor { + width: (container.width/2)-10; + + error: deviceHandler.frontRightError + speed: deviceHandler.frontRightSpeed + dcLink: deviceHandler.frontRightDcLink + voltage: deviceHandler.frontVoltage + } + + LivedataMotor { + width: (container.width/2)-10; + + error: deviceHandler.backLeftError + speed: deviceHandler.backLeftSpeed + dcLink: deviceHandler.backLeftDcLink + voltage: deviceHandler.backVoltage + } + + LivedataMotor { + width: (container.width/2)-10; + + error: deviceHandler.backRightError + speed: deviceHandler.backRightSpeed + dcLink: deviceHandler.backRightDcLink + voltage: deviceHandler.backVoltage + } + } + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: "Back: " + Number(deviceHandler.backVoltage).toLocaleString(Qt.locale()) + "V / " + Number(deviceHandler.backTemperature).toLocaleString(Qt.locale()) + "°C" + //visible: deviceHandler.alive + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + Image { + id: bobbycar + //anchors.horizontalCenter: flickable.horizontalCenter + //anchors.verticalCenter: flickable.bottom + width: parent.width * 0.2 + height: width + source: "images/logo.png" + smooth: true + antialiasing: true + + SequentialAnimation{ + id: bobbycarAnim + running: deviceHandler.alive + loops: Animation.Infinite + alwaysRunToEnd: true + PropertyAnimation { target: bobbycar; property: "scale"; to: 1.2; duration: 500; easing.type: Easing.InQuad } + PropertyAnimation { target: bobbycar; property: "scale"; to: 1.0; duration: 500; easing.type: Easing.OutQuad } + } + } + + Row { + Label { + text: 'iMotMax:' + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + SpinBox { + value: 50 + } + } + + Row { + Label { + text: 'iDcMax:' + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + SpinBox { + value: 50 + } + } + + Repeater { + model: 20 + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: "Placeholder" + //visible: deviceHandler.alive + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + } + } + } + } + + GameButton { + id: startButton + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: GameSettings.fieldMargin + width: container.width + height: GameSettings.fieldHeight + radius: GameSettings.buttonRadius + + onClicked: app.showPage("RemoteControl.qml") + + Text { + anchors.centerIn: parent + font.pixelSize: GameSettings.tinyFontSize + text: qsTr("REMOTE") + color: startButton.enabled ? GameSettings.textColor : GameSettings.disabledTextColor + } + } +} diff --git a/qml/LivedataMotor.qml b/qml/LivedataMotor.qml new file mode 100644 index 0000000..0bcf380 --- /dev/null +++ b/qml/LivedataMotor.qml @@ -0,0 +1,54 @@ +import QtQuick 2.15 + +Rectangle { + color: GameSettings.delegate1Color + height: width*0.8 + + property int error; + property real speed; + property real dcLink; + property real voltage; + property real power: voltage * dcLink; + + Column { + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: ["OK", "HALL miss", "HALL short", "MOTOR"][error] + " (" + error + ")"; + color: error == 0 ? "green" : "red" + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: Number(speed).toLocaleString(Qt.locale()) + "km/h" + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: Number(dcLink).toLocaleString(Qt.locale()) + "A" + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + + Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: Number(power>1000?(power/1000):power).toLocaleString(Qt.locale()) + (power > 1000 ? "kW" : "W") + color: GameSettings.textColor + minimumPixelSize: 10 + font.pixelSize: GameSettings.mediumFontSize + } + } +} diff --git a/qml/Measure.qml b/qml/Measure.qml deleted file mode 100644 index f026510..0000000 --- a/qml/Measure.qml +++ /dev/null @@ -1,194 +0,0 @@ -import QtQuick 2.5 - -GamePage { - id: measurePage - - errorMessage: deviceHandler.error - infoMessage: deviceHandler.info - - property real __timeCounter: 0; - property real __maxTimeCount: 60 - property string relaxText: qsTr("FAST!\nWhen you are ready, press Start. You have %1s time to increase speed so much as possible.\nGood luck!").arg(__maxTimeCount) - - function close() - { - deviceHandler.stopMeasurement(); - deviceHandler.disconnectService(); - app.prevPage(); - } - - function start() - { - if (!deviceHandler.measuring) { - __timeCounter = 0; - deviceHandler.startMeasurement() - } - } - - function stop() - { - if (deviceHandler.measuring) { - deviceHandler.stopMeasurement() - } - - app.showPage("Stats.qml") - } - - Timer { - id: measureTimer - interval: 1000 - running: deviceHandler.measuring - repeat: true - onTriggered: { - __timeCounter++; - if (__timeCounter >= __maxTimeCount) - measurePage.stop() - } - } - - Column { - anchors.centerIn: parent - spacing: GameSettings.fieldHeight * 0.5 - - Rectangle { - id: circle - anchors.horizontalCenter: parent.horizontalCenter - width: Math.min(measurePage.width, measurePage.height-GameSettings.fieldHeight*4) - 2*GameSettings.fieldMargin - height: width - radius: width*0.5 - color: GameSettings.viewColor - - Text { - id: hintText - anchors.centerIn: parent - anchors.verticalCenterOffset: -parent.height*0.1 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - width: parent.width * 0.8 - height: parent.height * 0.6 - wrapMode: Text.WordWrap - text: measurePage.relaxText - visible: !deviceHandler.measuring - color: GameSettings.textColor - fontSizeMode: Text.Fit - minimumPixelSize: 10 - font.pixelSize: GameSettings.mediumFontSize - } - - Text { - id: text - anchors.centerIn: parent - anchors.verticalCenterOffset: -parent.height*0.15 - font.pixelSize: parent.width * 0.45 - text: deviceHandler.speed.toFixed(0) - visible: deviceHandler.measuring - color: GameSettings.textColor - } - - Item { - id: minMaxContainer - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width*0.7 - height: parent.height * 0.15 - anchors.bottom: parent.bottom - anchors.bottomMargin: parent.height*0.16 - visible: deviceHandler.measuring - - Text { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - text: deviceHandler.minSpeed.toFixed(0) - color: GameSettings.textColor - font.pixelSize: GameSettings.hugeFontSize - - Text { - anchors.left: parent.left - anchors.bottom: parent.top - font.pixelSize: parent.font.pixelSize*0.8 - color: parent.color - text: "MIN" - } - } - - Text { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - text: deviceHandler.maxSpeed.toFixed(0) - color: GameSettings.textColor - font.pixelSize: GameSettings.hugeFontSize - - Text { - anchors.right: parent.right - anchors.bottom: parent.top - font.pixelSize: parent.font.pixelSize*0.8 - color: parent.color - text: "MAX" - } - } - } - - Image { - id: bobbycar - anchors.horizontalCenter: minMaxContainer.horizontalCenter - anchors.verticalCenter: minMaxContainer.bottom - width: parent.width * 0.2 - height: width - source: "images/logo.png" - smooth: true - antialiasing: true - - SequentialAnimation{ - id: bobbycarAnim - running: deviceHandler.alive - loops: Animation.Infinite - alwaysRunToEnd: true - PropertyAnimation { target: bobbycar; property: "scale"; to: 1.2; duration: 500; easing.type: Easing.InQuad } - PropertyAnimation { target: bobbycar; property: "scale"; to: 1.0; duration: 500; easing.type: Easing.OutQuad } - } - } - } - - Rectangle { - id: timeSlider - color: GameSettings.viewColor - anchors.horizontalCenter: parent.horizontalCenter - width: circle.width - height: GameSettings.fieldHeight - radius: GameSettings.buttonRadius - - Rectangle { - height: parent.height - radius: parent.radius - color: GameSettings.sliderColor - width: Math.min(1.0,__timeCounter / __maxTimeCount) * parent.width - } - - Text { - anchors.centerIn: parent - color: "gray" - text: (__maxTimeCount - __timeCounter).toFixed(0) + " s" - font.pixelSize: GameSettings.bigFontSize - } - } - } - - GameButton { - id: startButton - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - anchors.bottomMargin: GameSettings.fieldMargin - width: circle.width - height: GameSettings.fieldHeight - enabled: !deviceHandler.measuring - radius: GameSettings.buttonRadius - - onClicked: start() - - Text { - anchors.centerIn: parent - font.pixelSize: GameSettings.tinyFontSize - text: qsTr("START") - color: startButton.enabled ? GameSettings.textColor : GameSettings.disabledTextColor - } - } -} diff --git a/qml/RemoteControl.qml b/qml/RemoteControl.qml new file mode 100644 index 0000000..7e1ff87 --- /dev/null +++ b/qml/RemoteControl.qml @@ -0,0 +1,40 @@ +import QtQuick 2.15 + +GamePage { + id: remoteControlPage + + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: container.top + anchors.bottomMargin: GameSettings.fieldMargin + + font.pixelSize: GameSettings.hugeFontSize + color: GameSettings.textColor + text: qsTr("REMOTE CONTROL") + } + + Rectangle { + id: container + anchors.centerIn: parent + anchors.horizontalCenter: parent.horizontalCenter + width: Math.min(remoteControlPage.width, remoteControlPage.height-GameSettings.fieldHeight*4) - 2*GameSettings.fieldMargin + height: width + radius: GameSettings.buttonRadius + color: GameSettings.viewColor + + PointHandler { + id: handler + //acceptedDevices: PointerDevice.TouchScreen + target: Rectangle { + parent: container + color: "red" + visible: handler.active + x: handler.point.position.x - width / 2 + y: handler.point.position.y - height / 2 + width: 20 + height: width + radius: width / 2 + } + } + } +} diff --git a/qml/SplashScreen.qml b/qml/SplashScreen.qml index ebcb663..26f6808 100644 --- a/qml/SplashScreen.qml +++ b/qml/SplashScreen.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 import "." Item { diff --git a/qml/Stats.qml b/qml/Stats.qml deleted file mode 100644 index 7b6827d..0000000 --- a/qml/Stats.qml +++ /dev/null @@ -1,49 +0,0 @@ -import QtQuick 2.5 - -GamePage { - - Column { - anchors.centerIn: parent - width: parent.width - - Text { - anchors.horizontalCenter: parent.horizontalCenter - font.pixelSize: GameSettings.hugeFontSize - color: GameSettings.textColor - text: qsTr("RESULT") - } - - Text { - anchors.horizontalCenter: parent.horizontalCenter - font.pixelSize: GameSettings.giganticFontSize*3 - color: GameSettings.textColor - text: (deviceHandler.maxSpeed - deviceHandler.minSpeed).toFixed(0) - } - - Item { - height: GameSettings.fieldHeight - width: 1 - } - - StatsLabel { - title: qsTr("MIN") - value: deviceHandler.minSpeed.toFixed(0) - } - - StatsLabel { - title: qsTr("MAX") - value: deviceHandler.maxSpeed.toFixed(0) - } - - StatsLabel { - title: qsTr("AVG") - value: deviceHandler.avgSpeed.toFixed(1) - } - - - StatsLabel { - title: qsTr("DISTANCE") - value: deviceHandler.distance.toFixed(3) - } - } -} diff --git a/qml/StatsLabel.qml b/qml/StatsLabel.qml index 966b791..e2e95fd 100644 --- a/qml/StatsLabel.qml +++ b/qml/StatsLabel.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 import "." Item { diff --git a/qml/TitleBar.qml b/qml/TitleBar.qml index 1e980a3..0e9df7f 100644 --- a/qml/TitleBar.qml +++ b/qml/TitleBar.qml @@ -1,4 +1,4 @@ -import QtQuick 2.5 +import QtQuick 2.15 Rectangle { id: titleBar @@ -8,7 +8,7 @@ Rectangle { height: GameSettings.fieldHeight color: GameSettings.viewColor - property var __titles: ["CONNECT", "MEASURE", "STATS"] + property var __titles: ["CONNECT", "LIVEDATA", "REMOTECONTROL"] property int currentIndex: 0 signal titleClicked(int index) diff --git a/qml/main.qml b/qml/main.qml index 036c96d..8d8e8f3 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -1,5 +1,5 @@ -import QtQuick 2.7 -import QtQuick.Window 2.2 +import QtQuick 2.15 +import QtQuick.Window 2.15 import "." Window {