Compare commits

...

10 Commits

Author SHA1 Message Date
Roberto Viola
d1827a48ee version 2.19.0 2025-06-17 05:21:55 +02:00
Roberto Viola
f5c1b175a5 Merge branch 'master' of https://github.com/cagnulein/qdomyos-zwift 2025-06-17 03:15:55 +00:00
Roberto Viola
76b14cccb4 Nordictrack Elite 800 not accepting speed/incline changes from QZ (Issue #3393) 2025-06-17 03:15:45 +00:00
Adam Sharpe
19efaf6878 feat: Add elapsed time to FTMS virtual treadmill characteristic (#3491) 2025-06-17 04:59:05 +02:00
Roberto Viola
61a96dbc63 Update proformtreadmill.cpp 2025-06-16 15:23:27 +02:00
Roberto Viola
656f2b366b Nordictrack Elite 800 not accepting speed/incline changes from QZ (Issue #3393) 2025-06-16 15:03:15 +02:00
Roberto Viola
ee336436e7 Help with a Expert SX9 #3436 2025-06-16 12:28:58 +02:00
Roberto Viola
739270b944 Help with a Expert SX9 #3436 2025-06-16 11:55:59 +02:00
Roberto Viola
bcaf466fa1 Mobvoi Treadmill Plus 2025-06-16 10:50:04 +02:00
Roberto Viola
196f77d22a Think Rider X5 compability (Issue #3487) 2025-06-13 11:26:17 +02:00
8 changed files with 44 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<manifest package="org.cagnulen.qdomyoszwift" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionName="2.18.25" android:versionCode="1090" android:installLocation="auto">
<manifest package="org.cagnulen.qdomyoszwift" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionName="2.19.0" android:versionCode="1102" android:installLocation="auto">
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->

View File

@@ -1,6 +1,7 @@
#include "characteristicnotifier2acd.h"
#include "devices/treadmill.h"
#include <qmath.h>
#include <QTime> // Include QTime for Bike->elapsedTime()
CharacteristicNotifier2ACD::CharacteristicNotifier2ACD(bluetoothdevice *Bike, QObject *parent)
: CharacteristicNotifier(0x2acd, parent), Bike(Bike) {}
@@ -9,7 +10,8 @@ int CharacteristicNotifier2ACD::notify(QByteArray &value) {
bluetoothdevice::BLUETOOTH_TYPE dt = Bike->deviceType();
if (dt == bluetoothdevice::TREADMILL || dt == bluetoothdevice::ELLIPTICAL) {
value.append(0x0C); // Inclination available and distance for peloton
value.append((char)0x01); // heart rate available
//value.append((char)0x01); // heart rate available
value.append((char)0x05); // HeartRate(8) | ElapsedTime(10)
uint16_t normalizeSpeed = (uint16_t)qRound(Bike->currentSpeed().value() * 100);
char a = (normalizeSpeed >> 8) & 0XFF;
@@ -61,6 +63,18 @@ int CharacteristicNotifier2ACD::notify(QByteArray &value) {
rampBytes.append(b);
rampBytes.append(a);
// Get session elapsed time - makes Runna calculations work
QTime sessionElapsedTime = Bike->elapsedTime();
double elapsed_time_seconds =
(double)sessionElapsedTime.hour() * 3600.0 +
(double)sessionElapsedTime.minute() * 60.0 +
(double)sessionElapsedTime.second() +
(double)sessionElapsedTime.msec() / 1000.0;
uint16_t ftms_elapsed_time_field = (uint16_t)qRound(elapsed_time_seconds);
QByteArray elapsedBytes;
elapsedBytes.append(static_cast<char>(ftms_elapsed_time_field & 0xFF));
elapsedBytes.append(static_cast<char>((ftms_elapsed_time_field >> 8) & 0xFF));
value.append(speedBytes); // Actual value.
value.append(distanceBytes); // Actual value.
@@ -70,6 +84,9 @@ int CharacteristicNotifier2ACD::notify(QByteArray &value) {
value.append(rampBytes); // ramp angle
value.append(Bike->currentHeart().value()); // current heart rate
value.append(elapsedBytes); // Elapsed Time
return CN_OK;
} else
return CN_INVALID;

View File

@@ -1450,6 +1450,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) {
(b.name().toUpper().startsWith(QStringLiteral("ST90")) && deviceHasService(b, QBluetoothUuid((quint16)0x1826))) ||
(b.name().toUpper().startsWith(QStringLiteral("XT485")) && deviceHasService(b, QBluetoothUuid((quint16)0x1826))) ||
b.name().toUpper().startsWith(QStringLiteral("MOBVOI TM")) || // FTMS
b.name().toUpper().startsWith(QStringLiteral("MOBVOI WMTP")) || // FTMS
b.name().toUpper().startsWith(QStringLiteral("LB600")) || // FTMS
b.name().toUpper().startsWith(QStringLiteral("TUNTURI T60-")) || // FTMS
b.name().toUpper().startsWith(QStringLiteral("TUNTURI T80-")) || // FTMS
@@ -1559,6 +1560,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) {
} else if ((b.name().toUpper().startsWith("TACX ") ||
b.name().toUpper().startsWith(QStringLiteral("THINK X")) ||
b.name().toUpper().startsWith(QStringLiteral("THINK-")) ||
b.name().toUpper().startsWith(QStringLiteral("THINK_")) ||
b.name().toUpper().startsWith(QStringLiteral("53997-")) ||
(b.name().toUpper().startsWith("VANRYSEL-HT")) ||
b.address() == QBluetoothAddress("C1:14:D9:9C:FB:01") || // specific TACX NEO 2 #1707

View File

@@ -232,7 +232,10 @@ resistance_t ftmsbike::resistanceFromPowerRequest(uint16_t power) {
if (power < wattsFromResistance(1))
return 1;
else
return max_resistance;
if(DU30_bike)
return max_resistance;
else
return _ergTable.getMaxResistance();
}
void ftmsbike::forceResistance(resistance_t requestResistance) {

View File

@@ -3141,7 +3141,7 @@ void proformtreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha
(newValue.at(4) != 0x02 || newValue.at(5) != 0x2e)) ||
((nordictrack_elite_800) &&
(newValue.at(4) != 0x02 || newValue.at(5) != 0x2f)) ||
((uint8_t)newValue.at(18)) == 0xFF && ((uint8_t)newValue.at(19)) == 0xFF) ||
(((uint8_t)newValue.at(12)) == 0xFF && ((uint8_t)newValue.at(13)) == 0xFF &&
((uint8_t)newValue.at(14)) == 0xFF && ((uint8_t)newValue.at(15)) == 0xFF &&
@@ -6158,12 +6158,12 @@ void proformtreadmill::btinit() {
0x0f, 0x80, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t initData31[] = {0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x82, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t initData32[] = {0xfe, 0x02, 0x0d, 0x02};
/*uint8_t initData32[] = {0xfe, 0x02, 0x0d, 0x02};
uint8_t initData33[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x04, 0x09, 0x02, 0x02,
0x00, 0x10, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t initData34[] = {0xfe, 0x02, 0x0f, 0x02};
uint8_t initData35[] = {0xff, 0x0f, 0x02, 0x04, 0x02, 0x0b, 0x04, 0x0b, 0x02, 0x02,
0x02, 0x10, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x00, 0x00};
0x02, 0x10, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x00, 0x00};*/
writeCharacteristic(initData1, sizeof(initData1), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
@@ -6227,14 +6227,14 @@ void proformtreadmill::btinit() {
QThread::msleep(sleepms);
writeCharacteristic(initData31, sizeof(initData31), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
writeCharacteristic(initData32, sizeof(initData32), QStringLiteral("init"), false, false);
/*writeCharacteristic(initData32, sizeof(initData32), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
writeCharacteristic(initData33, sizeof(initData33), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
writeCharacteristic(initData34, sizeof(initData34), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
writeCharacteristic(initData35, sizeof(initData35), QStringLiteral("init"), false, false);
QThread::msleep(sleepms);
QThread::msleep(sleepms); */
} else if (nordictrack_t65s_treadmill_81_miles) {
uint8_t initData1[] = {0xfe, 0x02, 0x08, 0x02};
uint8_t initData2[] = {0xff, 0x08, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x81, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

View File

@@ -192,6 +192,18 @@ class ergTable : public QObject {
return wattageData;
}
uint16_t getMaxResistance() const {
if (consolidatedData.isEmpty()) return 0;
uint16_t maxRes = 0;
for (const auto& point : consolidatedData) {
if (point.resistance > maxRes) {
maxRes = point.resistance;
}
}
return maxRes;
}
private:
QMap<CadenceResistancePair, WattageStats> wattageData;
QList<ergDataPoint> consolidatedData;

View File

@@ -844,7 +844,7 @@ ApplicationWindow {
}
ItemDelegate {
text: "version 2.18.25"
text: "version 2.19.0"
width: parent.width
}

View File

@@ -979,4 +979,4 @@ INCLUDEPATH += purchasing/inapp
WINRT_MANIFEST = AppxManifest.xml
VERSION = 2.18.25
VERSION = 2.19.0