Skip to content

Commit fb28c98

Browse files
authored
Toputure 2026 FTMS: very low watt reading and too high initial resist… (#4592)
1 parent 5b0c005 commit fb28c98

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

src/devices/ftmsbike/ftmsbike.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ void ftmsbike::forceResistance(resistance_t requestResistance) {
269269
requestResistance = 1;
270270
}
271271

272-
if(SL010 || SPORT01)
272+
if(SL010 || SPORT01 || TOPUTURE_TEB5)
273273
Resistance = requestResistance;
274274

275275
if(JFBK5_0 || DIRETO_XR || YPBM || FIT_BK || ZIPRO_RAVE || SPEEDRACEX || MRK_S28 || USDC_D700) {
@@ -825,7 +825,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris
825825
if(BIKE_)
826826
d = d / 10.0;
827827
// for this bike, i will use the resistance that I set directly because the bike sends a different ratio.
828-
if(!SL010 && !TITAN_7000 && !SPORT01) {
828+
if(!SL010 && !TITAN_7000 && !SPORT01 && !TOPUTURE_TEB5) {
829829
Resistance = d;
830830
native_resistance_received = true;
831831
calculatedResistanceFallbackSince = QDateTime();
@@ -903,6 +903,31 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris
903903

904904
emit debug(QStringLiteral("Current Watt (SPORT01 formula - R%1 x%2): %3")
905905
.arg(resistance_level).arg(k[resistance_level - 1]).arg(m_watt.value()));
906+
} else if (TOPUTURE_TEB5 && settings.value(QZSettings::toputure_teb1, QZSettings::default_toputure_teb1).toBool()) {
907+
// Custom power calculation for TOPUTURE_TEB5
908+
// Resistance multipliers for levels 1-32
909+
const double k[32] = {0.60, 0.64, 0.68, 0.72, 0.76, 0.80, 0.84, 0.88, 0.92, 0.96, 1.00, 1.05, 1.10, 1.15, 1.20, 1.26, 1.32, 1.39, 1.46, 1.54, 1.62, 1.70, 1.79, 1.88, 1.97, 2.05, 2.12, 2.18, 2.24, 2.30, 2.35, 2.40};
910+
911+
// Baseline power curve coefficients (MyWhoosh cadence-power at resistance 5)
912+
double ac = 0.01243107769;
913+
double bc = 1.145964912;
914+
double cc = -23.50977444;
915+
916+
// Calculate baseline power from cadence (resistance level 5 baseline)
917+
double baseline_watt = ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc;
918+
919+
// Get current resistance level (1-32) and apply multiplier
920+
int resistance_level = (int)Resistance.value();
921+
if(resistance_level < 1) resistance_level = 1;
922+
if(resistance_level > 32) resistance_level = 32;
923+
924+
// Apply resistance multiplier
925+
m_watt = baseline_watt * k[resistance_level - 1];
926+
927+
if(m_watt.value() < 0) m_watt = 0;
928+
929+
emit debug(QStringLiteral("Current Watt (TOPUTURE_TEB5 formula - R%1 x%2): %3")
930+
.arg(resistance_level).arg(k[resistance_level - 1]).arg(m_watt.value()));
906931
} else if (MRK_S26C) {
907932
m_watt = Cadence.value() * (Resistance.value() * 1.16);
908933
emit debug(QStringLiteral("Current Watt (MRK-S26C formula): ") + QString::number(m_watt.value()));
@@ -2010,6 +2035,12 @@ void ftmsbike::deviceDiscovered(const QBluetoothDeviceInfo &device) {
20102035
resistance_lvl_mode = true;
20112036
ergModeSupported = false;
20122037
max_resistance = 32;
2038+
} else if(device.name().toUpper().startsWith("TOPUTURE TEB5")) {
2039+
qDebug() << QStringLiteral("TOPUTURE TEB5 found");
2040+
TOPUTURE_TEB5 = true;
2041+
max_resistance = 32;
2042+
ergModeSupported = false;
2043+
Resistance = 1; // Initialize resistance to 1 for SPORT01
20132044
} else if(device.name().toUpper().startsWith("SPORT01")) {
20142045
qDebug() << QStringLiteral("SPORT01 found");
20152046
SPORT01 = true;

src/devices/ftmsbike/ftmsbike.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class ftmsbike : public bike {
184184
bool ZIPRO_RAVE = false;
185185
bool SPEEDRACEX = false;
186186
bool USDC_D700 = false;
187+
bool TOPUTURE_TEB5 = false;
187188

188189
uint8_t secondsToResetTimer = 5;
189190

0 commit comments

Comments
 (0)