diff --git a/src/devices/apexbike/apexbike.cpp b/src/devices/apexbike/apexbike.cpp index b7ab04ff6..d8bb3a095 100644 --- a/src/devices/apexbike/apexbike.cpp +++ b/src/devices/apexbike/apexbike.cpp @@ -97,10 +97,7 @@ void apexbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); diff --git a/src/devices/apexbike/apexbike.h b/src/devices/apexbike/apexbike.h index 88d90843d..4f0fafa1a 100644 --- a/src/devices/apexbike/apexbike.h +++ b/src/devices/apexbike/apexbike.h @@ -38,8 +38,10 @@ class apexbike : public bike { apexbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); bool connected() override; + minmax resistanceLimits() override {return minmax(1,32);} + private: - const resistance_t max_resistance = 32; + void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); diff --git a/src/devices/bike.cpp b/src/devices/bike.cpp index 69872c165..0895db2a9 100644 --- a/src/devices/bike.cpp +++ b/src/devices/bike.cpp @@ -40,12 +40,22 @@ void bike::changeInclination(double grade, double percentage) { } // originally made for renphobike, but i guess it could be very generic -uint16_t bike::powerFromResistanceRequest(resistance_t requestResistance) { +uint16_t bike::wattsFromResistance(resistance_t resistance) { + auto minMaxR = this->resistanceLimits(); + if(resistance<=minMaxR.min()) + return 0; + // this bike has resistance level to N.m so the formula is Power (kW) = Torque (N.m) x Speed (RPM) / 9.5488 - double cadence = RequestedCadence.value(); + double cadence = this->RequestedCadence.value(); if (cadence <= 0) cadence = Cadence.value(); - return (requestResistance * cadence) / 9.5488; + + if(cadence <= this->cadenceLimits().min()) + return 0; + + resistance = minMaxR.clip(resistance); + + return (resistance * this->cadenceLimits().clip(cadence)) / 9.5488; } void bike::changeRequestedPelotonResistance(int8_t resistance) { RequestedPelotonResistance = resistance; } @@ -103,8 +113,57 @@ uint8_t bike::fanSpeed() { return FanSpeed; } bool bike::connected() { return false; } uint16_t bike::watts() { return 0; } metric bike::pelotonResistance() { return m_pelotonResistance; } -resistance_t bike::pelotonToBikeResistance(int pelotonResistance) { return pelotonResistance; } -resistance_t bike::resistanceFromPowerRequest(uint16_t power) { return power / 10; } // in order to have something + +resistance_t bike::pelotonToBikeResistance(int pelotonResistance) { + + auto minMaxR = this->resistanceLimits(); + + auto pr0 = bikeResistanceToPeloton(minMaxR.min()); + + if(pelotonResistance<=pr0) + return minMaxR.min(); + + for (resistance_t i = 1+minMaxR.min(); i < minMaxR.max(); i++) { + auto pr1 = bikeResistanceToPeloton(i); + if (pr0 <= pelotonResistance && pr1 >= pelotonResistance) { + return i; + } + pr0 = pr1; + } + + return minMaxR.max(); +} +resistance_t bike::resistanceFromPowerRequest(uint16_t power) { + qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); + + QSettings settings; + + double watt_gain = settings.value(QZSettings::watt_gain, QZSettings::default_watt_gain).toDouble(); + double watt_offset = settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); + + auto minMaxR = this->resistanceLimits(); + + uint16_t power0 = (wattsFromResistance(minMaxR.min()) * watt_gain) + watt_offset; + + // Is the requested power at or below the power of the minimum resistance the device provides? + if (power <= power0) + return minMaxR.min(); + + // Search from the 1st resistance level above minimum to the maximum + for (resistance_t i = 1 + minMaxR.min(); i < minMaxR.max(); i++) { + uint16_t power1 = wattsFromResistance(i)*watt_gain + watt_offset; + + if(power0 <= power && power1>=power) { + qDebug() << QStringLiteral("resistanceFromPowerRequest") << power0 << power1 << power; + return i; + } + + power0 = power1; + } + + // requested power requires resistance beyond the maximum + return minMaxR.max(); +} void bike::cadenceSensor(uint8_t cadence) { Cadence.setValue(cadence); } void bike::powerSensor(uint16_t power) { m_watt.setValue(power, false); } diff --git a/src/devices/bike.h b/src/devices/bike.h index 4f70e0ac5..3e5f0d23d 100644 --- a/src/devices/bike.h +++ b/src/devices/bike.h @@ -25,8 +25,10 @@ class bike : public bluetoothdevice { bool connected() override; virtual uint16_t watts(); virtual resistance_t pelotonToBikeResistance(int pelotonResistance); + virtual double bikeResistanceToPeloton(double resistance) { return resistance; } virtual resistance_t resistanceFromPowerRequest(uint16_t power); - virtual uint16_t powerFromResistanceRequest(resistance_t requestResistance); + virtual uint16_t wattsFromResistance(resistance_t resistance); + virtual bool ergManagedBySS2K() { return false; } bluetoothdevice::BLUETOOTH_TYPE deviceType() override; metric pelotonResistance(); @@ -48,6 +50,10 @@ class bike : public bluetoothdevice { virtual bool inclinationAvailableByHardware(); bool ergModeSupportedAvailableByHardware() { return ergModeSupported; } + /** + * @brief The inclusive minimum and maximum cadence values that power can be calculated for. + */ + virtual minmax cadenceLimits() { return minmax(0, 250); } public Q_SLOTS: void changeResistance(resistance_t res) override; virtual void changeCadence(int16_t cad); diff --git a/src/devices/bkoolbike/bkoolbike.cpp b/src/devices/bkoolbike/bkoolbike.cpp index 9cf2896e6..33a15f9e7 100644 --- a/src/devices/bkoolbike/bkoolbike.cpp +++ b/src/devices/bkoolbike/bkoolbike.cpp @@ -732,17 +732,6 @@ void bkoolbike::controllerStateChanged(QLowEnergyController::ControllerState sta } } -resistance_t bkoolbike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 0; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 0; - else - return max_resistance; -} double bkoolbike::bikeResistanceToPeloton(double resistance) { QSettings settings; diff --git a/src/devices/bkoolbike/bkoolbike.h b/src/devices/bkoolbike/bkoolbike.h index 8e1732bcb..c9f25ea8c 100644 --- a/src/devices/bkoolbike/bkoolbike.h +++ b/src/devices/bkoolbike/bkoolbike.h @@ -38,20 +38,18 @@ class bkoolbike : public bike { bkoolbike(bool noWriteResistance, bool noHeartService); void changePower(int32_t power) override; bool connected() override; - resistance_t pelotonToBikeResistance(int pelotonResistance); + minmax resistanceLimits() override {return minmax(1,100);} private: void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); void startDiscover(); void forceInclination(double inclination); uint16_t watts() override; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; QTimer *refresh; - const int max_resistance = 100; - QList gattCommunicationChannelService; QLowEnergyCharacteristic gattWriteCharControlPointId; QLowEnergyCharacteristic gattWriteCharCustomId; diff --git a/src/devices/bluetooth.cpp b/src/devices/bluetooth.cpp index 24e06cd26..ffab0ff3a 100644 --- a/src/devices/bluetooth.cpp +++ b/src/devices/bluetooth.cpp @@ -2293,7 +2293,7 @@ void bluetooth::connectedAndDiscovered() { #else settings.setValue(QZSettings::ftms_accessory_address, b.deviceUuid().toString()); #endif - ftmsAccessory = new smartspin2k(false, false, this->device()->maxResistance(), (bike *)this->device()); + ftmsAccessory = new smartspin2k(false, false, this->device()->resistanceLimits().max(), (bike *)this->device()); // connect(heartRateBelt, SIGNAL(disconnected()), this, SLOT(restart())); connect(ftmsAccessory, &smartspin2k::debug, this, &bluetooth::debug); diff --git a/src/devices/bluetoothdevice.cpp b/src/devices/bluetoothdevice.cpp index fbb9a0878..007ef14df 100644 --- a/src/devices/bluetoothdevice.cpp +++ b/src/devices/bluetoothdevice.cpp @@ -353,7 +353,6 @@ QStringList bluetoothdevice::metrics() { return r; } -resistance_t bluetoothdevice::maxResistance() { return 100; } uint8_t bluetoothdevice::metrics_override_heartrate() { diff --git a/src/devices/bluetoothdevice.h b/src/devices/bluetoothdevice.h index 9222c55aa..94b3f6ef0 100644 --- a/src/devices/bluetoothdevice.h +++ b/src/devices/bluetoothdevice.h @@ -2,6 +2,7 @@ #define BLUETOOTHDEVICE_H #include "definitions.h" +#include "minmax.h" #include "metric.h" #include "qzsettings.h" @@ -420,10 +421,20 @@ class bluetoothdevice : public QObject { */ virtual uint8_t metrics_override_heartrate(); + /** + * @brief Overridden in subclasses to specify the range of resistance levels supported by the device. + */ + virtual minmax resistanceLimits() { return minmax(0,100); } + /** * @brief Overridden in subclasses to specify the maximum resistance level supported by the device. */ - virtual resistance_t maxResistance(); + // virtual resistance_t maxResistance() { return 100; } + + /** + * @brief Overridden in subclasses to specify the minimum resistance level supported by the device. + */ + // virtual resistance_t minResistance() { return 0; } public Q_SLOTS: virtual void start(); diff --git a/src/devices/chronobike/chronobike.cpp b/src/devices/chronobike/chronobike.cpp index f9834c893..9e89f3217 100644 --- a/src/devices/chronobike/chronobike.cpp +++ b/src/devices/chronobike/chronobike.cpp @@ -93,11 +93,7 @@ void chronobike::update() { } if (requestResistance != -1) { - if (requestResistance > 15) { - requestResistance = 15; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/chronobike/chronobike.h b/src/devices/chronobike/chronobike.h index 88acbdb2a..afdd99495 100644 --- a/src/devices/chronobike/chronobike.h +++ b/src/devices/chronobike/chronobike.h @@ -38,6 +38,8 @@ class chronobike : public bike { chronobike(bool noWriteResistance, bool noHeartService); bool connected() override; + minmax resistanceLimits() override {return minmax(1,15);} + private: // void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, // Unused // bool wait_for_response = false); diff --git a/src/devices/computrainerbike/computrainerbike.cpp b/src/devices/computrainerbike/computrainerbike.cpp index 12090c300..2b150acf9 100644 --- a/src/devices/computrainerbike/computrainerbike.cpp +++ b/src/devices/computrainerbike/computrainerbike.cpp @@ -74,28 +74,6 @@ computrainerbike::computrainerbike(bool noWriteResistance, bool noHeartService, // ******************************************************************************************************** } -resistance_t computrainerbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - QSettings settings; - - double watt_gain = settings.value(QZSettings::watt_gain, QZSettings::default_watt_gain).toDouble(); - double watt_offset = settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (((wattsFromResistance(i) * watt_gain) + watt_offset) <= power && - ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") - << ((wattsFromResistance(i) * watt_gain) + watt_offset) - << ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) << power; - return i; - } - } - if (power < ((wattsFromResistance(1) * watt_gain) + watt_offset)) - return 1; - else - return max_resistance; -} uint16_t computrainerbike::wattsFromResistance(resistance_t resistance) { @@ -183,13 +161,9 @@ void computrainerbike::innerWriteResistance() { bool erg_mode = settings.value(QZSettings::zwift_erg, QZSettings::default_zwift_erg).toBool(); if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance < min_resistance) { - requestResistance = min_resistance; - } else if (requestResistance == 0) { - requestResistance = 1; - } + + requestResistance = resistanceLimits().clip(requestResistance); + if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -342,55 +316,21 @@ bool computrainerbike::inclinationAvailableByHardware() { return false; } +std::vector computrainerbike::bikeToPeloton({ 10,20,25,30,35,40,45,50,55,60,65,70,75,80,85,100 }); + +double computrainerbike::bikeResistanceToPeloton(double resistance) { + + auto r = this->resistanceLimits().clip(resistance); + + return bikeToPeloton[r-1]; +} + resistance_t computrainerbike::pelotonToBikeResistance(int pelotonResistance) { - if (pelotonResistance <= 10) { - return 1; - } - if (pelotonResistance <= 20) { - return 2; - } - if (pelotonResistance <= 25) { - return 3; - } - if (pelotonResistance <= 30) { - return 4; - } - if (pelotonResistance <= 35) { - return 5; - } - if (pelotonResistance <= 40) { - return 6; - } - if (pelotonResistance <= 45) { - return 7; - } - if (pelotonResistance <= 50) { - return 8; - } - if (pelotonResistance <= 55) { - return 9; - } - if (pelotonResistance <= 60) { - return 10; - } - if (pelotonResistance <= 65) { - return 11; - } - if (pelotonResistance <= 70) { - return 12; - } - if (pelotonResistance <= 75) { - return 13; - } - if (pelotonResistance <= 80) { - return 14; - } - if (pelotonResistance <= 85) { - return 15; - } - if (pelotonResistance <= 100) { - return 16; - } + + for(int i=0; i resistanceLimits() override {return minmax(1,16);} // limits inferred from Peloton conversion bool inclinationAvailableByHardware() override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: - resistance_t max_resistance = 100; - resistance_t min_resistance = -20; - uint16_t wattsFromResistance(resistance_t resistance); + /** + * @brief A mapping of peloton->(resistance-1) + */ + static std::vector bikeToPeloton; + double GetDistanceFromPacket(QByteArray packet); QTime GetElapsedFromPacket(QByteArray packet); void btinit(); diff --git a/src/devices/cscbike/cscbike.cpp b/src/devices/cscbike/cscbike.cpp index fa31fb9d0..a8337c5e5 100644 --- a/src/devices/cscbike/cscbike.cpp +++ b/src/devices/cscbike/cscbike.cpp @@ -105,11 +105,7 @@ void cscbike::update() { } if (requestResistance != -1) { - if (requestResistance > 15) { - requestResistance = 15; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/cscbike/cscbike.h b/src/devices/cscbike/cscbike.h index 1c926efb4..6a3d3e49b 100644 --- a/src/devices/cscbike/cscbike.h +++ b/src/devices/cscbike/cscbike.h @@ -38,6 +38,7 @@ class cscbike : public bike { cscbike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice); bool connected() override; + minmax resistanceLimits() override {return minmax(1,15);} private: // void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, //Unused // bool wait_for_response = false); diff --git a/src/devices/domyosbike/domyosbike.cpp b/src/devices/domyosbike/domyosbike.cpp index c0522eb1c..773502c3b 100644 --- a/src/devices/domyosbike/domyosbike.cpp +++ b/src/devices/domyosbike/domyosbike.cpp @@ -246,11 +246,7 @@ void domyosbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance < 1) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -391,7 +387,7 @@ void domyosbike::characteristicChanged(const QLowEnergyCharacteristic &character Resistance = 1; } emit resistanceRead(Resistance.value()); - m_pelotonResistance = (Resistance.value() * 100) / max_resistance; + m_pelotonResistance = (Resistance.value() * 100) / this->resistanceLimits().max(); bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); @@ -666,31 +662,35 @@ bool domyosbike::connected() { } resistance_t domyosbike::pelotonToBikeResistance(int pelotonResistance) { - return (pelotonResistance * max_resistance) / 100; + return (pelotonResistance * this->resistanceLimits().max()) / 100; +} + +double domyosbike::bikeResistanceToPeloton(double resistance) { + return (int)(1+resistance * 100.0/this->resistanceLimits().max()); } resistance_t domyosbike::resistanceFromPowerRequest(uint16_t power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << currentCadence().value(); - for (resistance_t i = 1; i < max_resistance; i++) { + for (resistance_t i = this->resistanceLimits().min(); i < this->resistanceLimits().max(); i++) { if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { return i; } } - if (power < wattsFromResistance(1)) - return 1; + if (power < wattsFromResistance(this->resistanceLimits().min())) + return this->resistanceLimits().min(); else - return max_resistance; + return this->resistanceLimits().max(); } -uint16_t domyosbike::wattsFromResistance(double resistance) { +uint16_t domyosbike::wattsFromResistance(resistance_t resistance) { QSettings settings; if (!settings.value(QZSettings::domyos_bike_500_profile_v1, QZSettings::default_domyos_bike_500_profile_v1) .toBool() || resistance < 8) return ((10.39 + 1.45 * (resistance - 1.0)) * (exp(0.028 * (currentCadence().value())))); else { - switch ((int)resistance) { + switch (resistance) { case 8: return (13.6 * Cadence.value()) / 9.5488; case 9: diff --git a/src/devices/domyosbike/domyosbike.h b/src/devices/domyosbike/domyosbike.h index 2b7f7dc2d..7c2ef982e 100644 --- a/src/devices/domyosbike/domyosbike.h +++ b/src/devices/domyosbike/domyosbike.h @@ -40,16 +40,20 @@ class domyosbike : public bike { uint8_t bikeResistanceOffset = 4, double bikeResistanceGain = 1.0); resistance_t resistanceFromPowerRequest(uint16_t power) override; resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } + double bikeResistanceToPeloton(double resistance) override; + + minmax resistanceLimits() override {return minmax(1,15);} + ~domyosbike() override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; + private: double GetSpeedFromPacket(const QByteArray &packet); double GetInclinationFromPacket(QByteArray packet); double GetKcalFromPacket(const QByteArray &packet); double GetDistanceFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); void forceResistance(resistance_t requestResistance); void updateDisplay(uint16_t elapsed); void btinit_changyow(bool startTape); @@ -59,7 +63,6 @@ class domyosbike : public bike { void startDiscover(); uint16_t watts() override; - const resistance_t max_resistance = 15; QTimer *refresh; uint8_t firstVirtual = 0; uint8_t firstStateChanged = 0; diff --git a/src/devices/echelonconnectsport/echelonconnectsport.cpp b/src/devices/echelonconnectsport/echelonconnectsport.cpp index 8bb92d4f5..76883991e 100644 --- a/src/devices/echelonconnectsport/echelonconnectsport.cpp +++ b/src/devices/echelonconnectsport/echelonconnectsport.cpp @@ -125,10 +125,7 @@ void echelonconnectsport::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -157,34 +154,43 @@ void echelonconnectsport::serviceDiscovered(const QBluetoothUuid &gatt) { } resistance_t echelonconnectsport::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) > pelotonResistance) { + auto minMaxR = this->resistanceLimits(); + + auto p0 = bikeResistanceToPeloton(minMaxR.min()); + + if (pelotonResistance <= p0) + return minMaxR.min(); + + for (resistance_t i = 1+minMaxR.min(); i < minMaxR.max(); i++) { + auto p1 = bikeResistanceToPeloton(i); + if (p0 <= pelotonResistance && p1 > pelotonResistance) { return i; } + p0 = p1; } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; + + return minMaxR.max(); } resistance_t echelonconnectsport::resistanceFromPowerRequest(uint16_t power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); + auto minMaxR = this->resistanceLimits(); + if (Cadence.value() == 0) - return 1; + return minMaxR.min(); - for (resistance_t i = 1; i < max_resistance; i++) { + for (resistance_t i = 1; i < minMaxR.max(); i++) { if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) << wattsFromResistance(i + 1) << power; return i; } } - if (power < wattsFromResistance(1)) + if (power < wattsFromResistance(minMaxR.min())) return 1; else - return max_resistance; + return minMaxR.max(); } double echelonconnectsport::bikeResistanceToPeloton(double resistance) { @@ -537,7 +543,7 @@ uint16_t echelonconnectsport::watts() { return wattsFromResistance(Resistance.value()); } -uint16_t echelonconnectsport::wattsFromResistance(double resistance) { +uint16_t echelonconnectsport::wattsFromResistance(resistance_t resistance) { // https://github.com/cagnulein/qdomyos-zwift/issues/62#issuecomment-736913564 /*if(currentCadence().value() < 90) return (uint16_t)((3.59 * exp(0.0217 * (double)(currentCadence().value()))) * exp(0.095 * @@ -547,7 +553,7 @@ uint16_t echelonconnectsport::wattsFromResistance(double resistance) { const double Epsilon = 4.94065645841247E-324; const int wattTableFirstDimension = 33; const int wattTableSecondDimension = 11; - double wattTable[wattTableFirstDimension][wattTableSecondDimension] = { + static double wattTable[wattTableFirstDimension][wattTableSecondDimension] = { {Epsilon, 1.0, 2.2, 4.8, 9.5, 13.6, 16.7, 22.6, 26.3, 29.2, 47.0}, {Epsilon, 1.0, 2.2, 4.8, 9.5, 13.6, 16.7, 22.6, 26.3, 29.2, 47.0}, {Epsilon, 1.3, 3.0, 5.4, 10.4, 14.5, 18.5, 24.6, 27.6, 33.5, 49.5}, @@ -582,7 +588,7 @@ uint16_t echelonconnectsport::wattsFromResistance(double resistance) { {Epsilon, 12.5, 48.0, 99.3, 162.2, 232.9, 310.4, 400.3, 435.5, 530.5, 589.0}, {Epsilon, 13.0, 53.0, 102.0, 170.3, 242.0, 320.0, 427.9, 475.2, 570.0, 625.0}}; - double wattTable_mgarcea[wattTableFirstDimension][wattTableSecondDimension] = { + static double wattTable_mgarcea[wattTableFirstDimension][wattTableSecondDimension] = { {Epsilon, 1.0, 2.2, 4.8, 9.5, 13.6, 16.7, 22.6, 26.3, 29.2, 47.0}, {Epsilon, 1.0, 2.2, 4.8, 9.5, 13.6, 16.7, 22.6, 26.3, 29.2, 47.0}, {Epsilon, 1.3, 3.0, 5.4, 10.4, 14.5, 18.5, 24.6, 27.6, 33.5, 49.5}, diff --git a/src/devices/echelonconnectsport/echelonconnectsport.h b/src/devices/echelonconnectsport/echelonconnectsport.h index dff83d543..94a55b7f1 100644 --- a/src/devices/echelonconnectsport/echelonconnectsport.h +++ b/src/devices/echelonconnectsport/echelonconnectsport.h @@ -40,15 +40,16 @@ class echelonconnectsport : public bike { echelonconnectsport(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override { return minmax(1,32); } resistance_t resistanceFromPowerRequest(uint16_t power) override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; + private: - const resistance_t max_resistance = 32; double bikeResistanceToPeloton(double resistance); double GetDistanceFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); + QTime GetElapsedFromPacket(const QByteArray &packet); void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, diff --git a/src/devices/fakebike/fakebike.cpp b/src/devices/fakebike/fakebike.cpp index ef3e1f338..5fba19d58 100644 --- a/src/devices/fakebike/fakebike.cpp +++ b/src/devices/fakebike/fakebike.cpp @@ -165,7 +165,7 @@ void fakebike::changeInclinationRequested(double grade, double percentage) { changeInclination(grade, percentage); } -uint16_t fakebike::wattsFromResistance(double resistance) { +uint16_t fakebike::wattsFromResistance(resistance_t resistance) { return _ergTable.estimateWattage(Cadence.value(), resistance); } @@ -175,20 +175,22 @@ resistance_t fakebike::resistanceFromPowerRequest(uint16_t power) { /*if(toorx_srx_3500)*/ { qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); + auto minMaxR = this->resistanceLimits(); + if (Cadence.value() == 0) - return 1; + return minMaxR.min(); - for (resistance_t i = 1; i < maxResistance(); i++) { + for (resistance_t i = 1; i < minMaxR.max(); i++) { if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) << wattsFromResistance(i + 1) << power; return i; } } - if (power < wattsFromResistance(1)) - return 1; + if (power < wattsFromResistance(minMaxR.min())) + return minMaxR.min(); else - return maxResistance(); + return minMaxR.max(); } /*else { return power / 10; }*/ diff --git a/src/devices/fakebike/fakebike.h b/src/devices/fakebike/fakebike.h index e94ac4e14..676b1890c 100644 --- a/src/devices/fakebike/fakebike.h +++ b/src/devices/fakebike/fakebike.h @@ -40,8 +40,9 @@ class fakebike : public bike { fakebike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice); bool connected() override; uint16_t watts() override; - resistance_t maxResistance() override { return 100; } + minmax resistanceLimits() override {return minmax(1,100);} resistance_t resistanceFromPowerRequest(uint16_t power) override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: QTimer *refresh; @@ -67,8 +68,7 @@ class fakebike : public bike { #ifdef Q_OS_IOS lockscreen *h = 0; #endif - - uint16_t wattsFromResistance(double resistance); + signals: void disconnected(); diff --git a/src/devices/fitplusbike/fitplusbike.cpp b/src/devices/fitplusbike/fitplusbike.cpp index 8578b8ab7..d80045732 100644 --- a/src/devices/fitplusbike/fitplusbike.cpp +++ b/src/devices/fitplusbike/fitplusbike.cpp @@ -343,11 +343,8 @@ void fitplusbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance <= 0) { - requestResistance = 1; - } + + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -584,7 +581,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); } else { - m_pelotonResistance = (100 * Resistance.value()) / max_resistance; + m_pelotonResistance = (100 * Resistance.value()) / this->resistanceLimits().max(); } if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) @@ -734,8 +731,7 @@ void fitplusbike::btinit() { writeCharacteristic(initData6, sizeof(initData6), QStringLiteral("init"), false, true); writeCharacteristic(initData1, sizeof(initData2), QStringLiteral("init"), false, false); - max_resistance = 32; - + this->bikeResistanceLimits = minmax(1,32); } else { uint8_t initData1[] = {0x02, 0x44, 0x01, 0x45, 0x03}; @@ -981,7 +977,7 @@ void fitplusbike::controllerStateChanged(QLowEnergyController::ControllerState s } } -uint16_t fitplusbike::wattsFromResistance(double resistance) { +uint16_t fitplusbike::wattsFromResistance(resistance_t resistance) { // https://github.com/cagnulein/qdomyos-zwift/issues/62#issuecomment-736913564 /*if(currentCadence().value() < 90) return (uint16_t)((3.59 * exp(0.0217 * (double)(currentCadence().value()))) * exp(0.095 * @@ -1076,21 +1072,3 @@ uint16_t fitplusbike::wattsFromResistance(double resistance) { } } -resistance_t fitplusbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - if (Cadence.value() == 0) - return 1; - - for (resistance_t i = 1; i < max_resistance; i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return max_resistance; -} diff --git a/src/devices/fitplusbike/fitplusbike.h b/src/devices/fitplusbike/fitplusbike.h index 2bc94257b..ed90f435b 100644 --- a/src/devices/fitplusbike/fitplusbike.h +++ b/src/devices/fitplusbike/fitplusbike.h @@ -37,12 +37,11 @@ class fitplusbike : public bike { Q_OBJECT public: fitplusbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return this->bikeResistanceLimits;} bool connected() override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: - resistance_t max_resistance = 24; void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); @@ -50,7 +49,7 @@ class fitplusbike : public bike { void forceResistance(resistance_t requestResistance); void sendPoll(); uint16_t watts() override; - uint16_t wattsFromResistance(double resistance); + QTimer *refresh; @@ -60,6 +59,7 @@ class fitplusbike : public bike { QLowEnergyCharacteristic gattNotify1Characteristic; QLowEnergyCharacteristic gattNotifyFTMSCharacteristic; + minmax bikeResistanceLimits{1,24}; uint8_t bikeResistanceOffset = 4; double bikeResistanceGain = 1.0; uint8_t counterPoll = 1; diff --git a/src/devices/flywheelbike/flywheelbike.cpp b/src/devices/flywheelbike/flywheelbike.cpp index 7ee06230a..ccf0347fc 100644 --- a/src/devices/flywheelbike/flywheelbike.cpp +++ b/src/devices/flywheelbike/flywheelbike.cpp @@ -81,11 +81,7 @@ void flywheelbike::update() { }*/ if (requestResistance != -1) { - if (requestResistance > 15) { - requestResistance = 15; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/flywheelbike/flywheelbike.h b/src/devices/flywheelbike/flywheelbike.h index 956b2d034..4a1f9df4c 100644 --- a/src/devices/flywheelbike/flywheelbike.h +++ b/src/devices/flywheelbike/flywheelbike.h @@ -38,6 +38,8 @@ class flywheelbike : public bike { flywheelbike(bool noWriteResistance, bool noHeartService); bool connected() override; + minmax resistanceLimits() override {return minmax(1,15);} + private: typedef enum DecoderRXState { WFSYNC_1 = 0, WFLENGTH, WFID, DATA, CHECKSUM, EOF_1 } DecoderRXState; diff --git a/src/devices/ftmsbike/ftmsbike.cpp b/src/devices/ftmsbike/ftmsbike.cpp index 6e124df7e..90361c1fe 100644 --- a/src/devices/ftmsbike/ftmsbike.cpp +++ b/src/devices/ftmsbike/ftmsbike.cpp @@ -96,7 +96,7 @@ void ftmsbike::forcePower(int16_t requestPower) { powerForced = true; } -uint16_t ftmsbike::wattsFromResistance(double resistance) { +uint16_t ftmsbike::wattsFromResistance(resistance_t resistance) { if(DU30_bike) { double y = 1.46193548 * Cadence.value() + 0.0000887836638 * Cadence.value() * resistance + 0.000625 * resistance * resistance + 0.0580645161 * Cadence.value() + 0.00292986091 * resistance + 6.48448135542904; return y; @@ -104,24 +104,6 @@ uint16_t ftmsbike::wattsFromResistance(double resistance) { return 1; } -resistance_t ftmsbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - if (Cadence.value() == 0) - return 1; - - for (resistance_t i = 1; i < max_resistance; i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return max_resistance; -} void ftmsbike::forceResistance(resistance_t requestResistance) { @@ -894,7 +876,7 @@ void ftmsbike::error(QLowEnergyController::Error err) { } resistance_t ftmsbike::pelotonToBikeResistance(int pelotonResistance) { - return (pelotonResistance * max_resistance) / 100; + return (pelotonResistance * this->resistanceLimits().max()) / 100; } void ftmsbike::deviceDiscovered(const QBluetoothDeviceInfo &device) { @@ -904,13 +886,13 @@ void ftmsbike::deviceDiscovered(const QBluetoothDeviceInfo &device) { bluetoothDevice = device; if (bluetoothDevice.name().toUpper().startsWith("SUITO")) { qDebug() << QStringLiteral("SUITO found"); - max_resistance = 16; + this->bikeResistanceLimits = minmax(1,16); } else if ((bluetoothDevice.name().toUpper().startsWith("MAGNUS "))) { qDebug() << QStringLiteral("MAGNUS found"); resistance_lvl_mode = true; } else if ((bluetoothDevice.name().toUpper().startsWith("DU30-"))) { qDebug() << QStringLiteral("DU30 found"); - max_resistance = 32; + this->bikeResistanceLimits = minmax(1,32); DU30_bike = true; } diff --git a/src/devices/ftmsbike/ftmsbike.h b/src/devices/ftmsbike/ftmsbike.h index 935a9c9b9..754821d90 100644 --- a/src/devices/ftmsbike/ftmsbike.h +++ b/src/devices/ftmsbike/ftmsbike.h @@ -71,8 +71,8 @@ class ftmsbike : public bike { ftmsbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); bool connected() override; resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } - resistance_t resistanceFromPowerRequest(uint16_t power) override; + minmax resistanceLimits() override {return this->bikeResistanceLimits;} + uint16_t wattsFromResistance(resistance_t resistance) override; private: void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, @@ -82,7 +82,7 @@ class ftmsbike : public bike { void init(); void forceResistance(resistance_t requestResistance); void forcePower(int16_t requestPower); - uint16_t wattsFromResistance(double resistance); + QTimer *refresh; @@ -96,7 +96,7 @@ class ftmsbike : public bike { uint8_t firstStateChanged = 0; uint8_t bikeResistanceOffset = 4; double bikeResistanceGain = 1.0; - int max_resistance = 100; + minmax bikeResistanceLimits { 1,100}; bool initDone = false; bool initRequest = false; diff --git a/src/devices/horizongr7bike/horizongr7bike.cpp b/src/devices/horizongr7bike/horizongr7bike.cpp index 4a9386957..3bae646a0 100644 --- a/src/devices/horizongr7bike/horizongr7bike.cpp +++ b/src/devices/horizongr7bike/horizongr7bike.cpp @@ -110,12 +110,7 @@ void horizongr7bike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } // TODO, use the bluetooth value - else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); // TODO, use the bluetooth value if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/horizongr7bike/horizongr7bike.h b/src/devices/horizongr7bike/horizongr7bike.h index 719ab0a42..291653a8e 100644 --- a/src/devices/horizongr7bike/horizongr7bike.h +++ b/src/devices/horizongr7bike/horizongr7bike.h @@ -40,6 +40,8 @@ class horizongr7bike : public bike { double bikeResistanceGain); bool connected() override; + minmax resistanceLimits() override {return minmax(1,12);} + private: void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); @@ -58,7 +60,7 @@ class horizongr7bike : public bike { QLowEnergyCharacteristic customWriteChar; double bikeResistanceToPeloton(double resistance); - const resistance_t max_resistance = 12; + uint8_t sec1Update = 0; QByteArray lastPacket; QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); diff --git a/src/devices/iconceptbike/iconceptbike.cpp b/src/devices/iconceptbike/iconceptbike.cpp index 308cd0744..08dabeb3f 100644 --- a/src/devices/iconceptbike/iconceptbike.cpp +++ b/src/devices/iconceptbike/iconceptbike.cpp @@ -104,11 +104,8 @@ void iconceptbike::update() { // ******************************************************************************************************** if (requestResistance != -1) { - if (requestResistance > 12) { - requestResistance = 12; - } else if (requestResistance < 1) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); + char resValues[] = {0x08, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x18}; char res[] = {0x55, 0x11, 0x01, 0x12}; res[3] = resValues[requestResistance - 1]; diff --git a/src/devices/iconceptbike/iconceptbike.h b/src/devices/iconceptbike/iconceptbike.h index 3011be72f..fe703efc6 100644 --- a/src/devices/iconceptbike/iconceptbike.h +++ b/src/devices/iconceptbike/iconceptbike.h @@ -34,6 +34,8 @@ class iconceptbike : public bike { public: explicit iconceptbike(); + minmax resistanceLimits() override {return minmax(1,12);} + public slots: void deviceDiscovered(const QBluetoothDeviceInfo &device); diff --git a/src/devices/inspirebike/inspirebike.cpp b/src/devices/inspirebike/inspirebike.cpp index bef594ab5..d7d0bb499 100644 --- a/src/devices/inspirebike/inspirebike.cpp +++ b/src/devices/inspirebike/inspirebike.cpp @@ -94,11 +94,7 @@ void inspirebike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -390,7 +386,7 @@ uint16_t inspirebike::watts() { -136.8333333, -132.3333333, -160, -66.16666667, -93.5, -131.5, -149.5, -92.16666667}; uint8_t res = qRound(currentResistance().value()); - if (res - 1 < max_resistance && res > 0) { + if (res - 1 < this->resistanceLimits().max() && res > 0) { double w = ((m[res - 1] * (double)(currentCadence().value())) + q[res - 1]); if (w < 0) w = 0; diff --git a/src/devices/inspirebike/inspirebike.h b/src/devices/inspirebike/inspirebike.h index 97303d6e2..ac9177c3f 100644 --- a/src/devices/inspirebike/inspirebike.h +++ b/src/devices/inspirebike/inspirebike.h @@ -37,10 +37,10 @@ class inspirebike : public bike { Q_OBJECT public: inspirebike(bool noWriteResistance, bool noHeartService); - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return minmax(1,40);} bool connected() override; - const resistance_t max_resistance = 40; + private: void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, diff --git a/src/devices/keepbike/keepbike.cpp b/src/devices/keepbike/keepbike.cpp index a80bb0391..b693b17b0 100644 --- a/src/devices/keepbike/keepbike.cpp +++ b/src/devices/keepbike/keepbike.cpp @@ -133,10 +133,7 @@ void keepbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -164,17 +161,6 @@ void keepbike::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); } -resistance_t keepbike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; -} double keepbike::bikeResistanceToPeloton(double resistance) { // 0,0097x3 - 0,4972x2 + 10,126x - 37,08 diff --git a/src/devices/keepbike/keepbike.h b/src/devices/keepbike/keepbike.h index 25305a2be..6bda7513b 100644 --- a/src/devices/keepbike/keepbike.h +++ b/src/devices/keepbike/keepbike.h @@ -37,13 +37,12 @@ class keepbike : public bike { Q_OBJECT public: keepbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } + + minmax resistanceLimits() override {return minmax(1,36);} bool connected() override; private: - const resistance_t max_resistance = 36; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; double GetDistanceFromPacket(const QByteArray &packet); double GetSpeedFromPacket(const QByteArray &packet); double GetWattFromPacket(const QByteArray &packet); diff --git a/src/devices/mcfbike/mcfbike.cpp b/src/devices/mcfbike/mcfbike.cpp index ecb65b27b..b1cd3c7a2 100644 --- a/src/devices/mcfbike/mcfbike.cpp +++ b/src/devices/mcfbike/mcfbike.cpp @@ -104,10 +104,7 @@ void mcfbike::update() { sendPoll(); if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -135,41 +132,14 @@ void mcfbike::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); } -resistance_t mcfbike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; -} - -resistance_t mcfbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return max_resistance; -} // TO CHANGE -uint16_t mcfbike::wattsFromResistance(double resistance) { +uint16_t mcfbike::wattsFromResistance(resistance_t resistance) { return ((10.39 + 1.45 * (resistance - 1.0)) * (exp(0.028 * (currentCadence().value())))); } double mcfbike::bikeResistanceToPeloton(double resistance) { - double p = resistance * (100.0 / max_resistance); + double p = resistance * (100.0 / this->resistanceLimits().max()); if (p < 0) { p = 0; } diff --git a/src/devices/mcfbike/mcfbike.h b/src/devices/mcfbike/mcfbike.h index 3f0106841..9ce8b4c34 100644 --- a/src/devices/mcfbike/mcfbike.h +++ b/src/devices/mcfbike/mcfbike.h @@ -36,16 +36,15 @@ class mcfbike : public bike { Q_OBJECT public: mcfbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; - resistance_t maxResistance() override { return max_resistance; } + + minmax resistanceLimits() override {return minmax(1,14);} bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: - const resistance_t max_resistance = 14; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; double GetDistanceFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); + QTime GetElapsedFromPacket(const QByteArray &packet); void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, diff --git a/src/devices/mepanelbike/mepanelbike.cpp b/src/devices/mepanelbike/mepanelbike.cpp index 917801757..4a27b4cce 100644 --- a/src/devices/mepanelbike/mepanelbike.cpp +++ b/src/devices/mepanelbike/mepanelbike.cpp @@ -98,10 +98,7 @@ void mepanelbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); diff --git a/src/devices/mepanelbike/mepanelbike.h b/src/devices/mepanelbike/mepanelbike.h index 861a3efa1..1e4c9238e 100644 --- a/src/devices/mepanelbike/mepanelbike.h +++ b/src/devices/mepanelbike/mepanelbike.h @@ -38,9 +38,9 @@ class mepanelbike : public bike { public: mepanelbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); bool connected() override; + minmax resistanceLimits() override {return minmax(1,32);} private: - const resistance_t max_resistance = 32; void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); diff --git a/src/devices/nautilusbike/nautilusbike.cpp b/src/devices/nautilusbike/nautilusbike.cpp index 7dde95c0e..344b14302 100644 --- a/src/devices/nautilusbike/nautilusbike.cpp +++ b/src/devices/nautilusbike/nautilusbike.cpp @@ -418,7 +418,7 @@ void nautilusbike::controllerStateChanged(QLowEnergyController::ControllerState uint16_t nautilusbike::watts() { return m_watt.value(); } -uint16_t nautilusbike::wattsFromResistance(double resistance) { +uint16_t nautilusbike::wattsFromResistance(resistance_t resistance) { // power table nautilus u626 #2118 double intercept = 12.16860795336126; double coefCadence = 0.12260211; @@ -440,23 +440,26 @@ uint16_t nautilusbike::wattsFromResistance(double resistance) { resistance_t nautilusbike::resistanceFromPowerRequest(uint16_t power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.average5s(); + auto minMaxR = this->resistanceLimits(); + if (Cadence.average5s() == 0) - return 1; + return minMaxR.min(); - for (resistance_t i = 1; i < maxResistance(); i++) { + for (resistance_t i = minMaxR.min(); i < minMaxR.max(); i++) { if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) << wattsFromResistance(i + 1) << power; return i; } } - if (power < wattsFromResistance(1)) - return 1; + if (power < wattsFromResistance(minMaxR.min())) + return minMaxR.min(); else - return maxResistance(); + return minMaxR.max(); } -resistance_t nautilusbike::maxResistance() { - // power table nautilus u626 #2118 - return 25; +minmax nautilusbike::resistanceLimits() { + return minmax(1,25);// power table nautilus u626 #2118 } + + diff --git a/src/devices/nautilusbike/nautilusbike.h b/src/devices/nautilusbike/nautilusbike.h index 9dc42192d..853a78c0b 100644 --- a/src/devices/nautilusbike/nautilusbike.h +++ b/src/devices/nautilusbike/nautilusbike.h @@ -36,8 +36,8 @@ class nautilusbike : public bike { ~nautilusbike(); bool connected() override; resistance_t resistanceFromPowerRequest(uint16_t power) override; - resistance_t maxResistance() override; - + minmax resistanceLimits() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: double GetSpeedFromPacket(const QByteArray &packet); double GetInclinationFromPacket(QByteArray packet); @@ -48,7 +48,7 @@ class nautilusbike : public bike { void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); void startDiscover(); - uint16_t wattsFromResistance(double resistance); + QTimer *refresh; uint8_t firstVirtual = 0; diff --git a/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.cpp b/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.cpp index 7f7bcf90b..f9bed221d 100644 --- a/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.cpp +++ b/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.cpp @@ -576,20 +576,24 @@ resistance_t nordictrackifitadbbike::resistanceFromPowerRequest(uint16_t power) // actually it's using inclination for the s22i qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); + auto minMaxR = this->resistanceLimits(); + if (Cadence.value() == 0) - return 0; + return minMaxR.min(); + + const double cadence = Cadence.value(); - for (resistance_t i = 0; i < max_resistance; i++) { - if (wattsFromResistance(i, Cadence.value()) <= power && wattsFromResistance(i + 1, Cadence.value()) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i, Cadence.value()) - << wattsFromResistance(i + 1, Cadence.value()) << power; + for (resistance_t i = minMaxR.min(); i < minMaxR.max(); i++) { + if (wattsFromResistance(i, cadence) <= power && wattsFromResistance(i + 1, cadence) >= power) { + qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i, cadence) + << wattsFromResistance(i + 1, cadence) << power; return i; } } - if (power < wattsFromResistance(0, Cadence.value())) - return 0; + if (power < wattsFromResistance(this->resistanceLimits().min(), cadence)) + return this->resistanceLimits().min(); else - return max_resistance; + return this->resistanceLimits().max(); } uint16_t nordictrackifitadbbike::wattsFromResistance(double inclination, double cadence) { diff --git a/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.h b/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.h index b873bb018..f1a92822c 100644 --- a/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.h +++ b/src/devices/nordictrackifitadbbike/nordictrackifitadbbike.h @@ -65,10 +65,14 @@ class nordictrackifitadbbike : public bike { bool connected() override; resistance_t pelotonToBikeResistance(int pelotonResistance) override; bool inclinationAvailableByHardware() override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; + resistance_t resistanceFromPowerRequest(uint16_t power) override; + minmax resistanceLimits() override { + return minmax(0,17); // max inclination for s22i + } + + uint16_t wattsFromResistance(resistance_t resistance) override { return this->wattsFromResistance(resistance, this->Cadence.value()); } private: - const resistance_t max_resistance = 17; // max inclination for s22i void forceResistance(double resistance); uint16_t watts() override; double getDouble(QString v); diff --git a/src/devices/npecablebike/npecablebike.cpp b/src/devices/npecablebike/npecablebike.cpp index 89a7c1d46..0c4e8db6a 100644 --- a/src/devices/npecablebike/npecablebike.cpp +++ b/src/devices/npecablebike/npecablebike.cpp @@ -78,11 +78,7 @@ void npecablebike::update() { } if (requestResistance != -1) { - if (requestResistance > 15) { - requestResistance = 15; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/npecablebike/npecablebike.h b/src/devices/npecablebike/npecablebike.h index afef77276..b695b4368 100644 --- a/src/devices/npecablebike/npecablebike.h +++ b/src/devices/npecablebike/npecablebike.h @@ -37,7 +37,7 @@ class npecablebike : public bike { public: npecablebike(bool noWriteResistance, bool noHeartService); bool connected() override; - + minmax resistanceLimits() override {return minmax(1,15);} private: void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); diff --git a/src/devices/pafersbike/pafersbike.cpp b/src/devices/pafersbike/pafersbike.cpp index 7b33f1e6b..d3447f718 100644 --- a/src/devices/pafersbike/pafersbike.cpp +++ b/src/devices/pafersbike/pafersbike.cpp @@ -112,10 +112,7 @@ void pafersbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -143,35 +140,7 @@ void pafersbike::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); } -resistance_t pafersbike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; -} - -resistance_t pafersbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return max_resistance; -} - -uint16_t pafersbike::wattsFromResistance(double resistance) { +uint16_t pafersbike::wattsFromResistance(resistance_t resistance) { // to be changed return ((10.39 + 1.45 * (resistance - 1.0)) * (exp(0.028 * (currentCadence().value())))); } diff --git a/src/devices/pafersbike/pafersbike.h b/src/devices/pafersbike/pafersbike.h index e424318c3..6dd535752 100644 --- a/src/devices/pafersbike/pafersbike.h +++ b/src/devices/pafersbike/pafersbike.h @@ -36,16 +36,16 @@ class pafersbike : public bike { Q_OBJECT public: pafersbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; - resistance_t maxResistance() override { return max_resistance; } + + minmax resistanceLimits() override {return minmax(1,24);} bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; + private: - const resistance_t max_resistance = 24; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; double GetDistanceFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); + QTime GetElapsedFromPacket(const QByteArray &packet); void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, diff --git a/src/devices/proformbike/proformbike.cpp b/src/devices/proformbike/proformbike.cpp index ecbdef1dc..9f473a987 100644 --- a/src/devices/proformbike/proformbike.cpp +++ b/src/devices/proformbike/proformbike.cpp @@ -55,35 +55,12 @@ void proformbike::writeCharacteristic(uint8_t *data, uint8_t data_len, const QSt loop.exec(); } -resistance_t proformbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - QSettings settings; - - double watt_gain = settings.value(QZSettings::watt_gain, QZSettings::default_watt_gain).toDouble(); - double watt_offset = settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (((wattsFromResistance(i) * watt_gain) + watt_offset) <= power && - ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") - << ((wattsFromResistance(i) * watt_gain) + watt_offset) - << ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) << power; - return i; - } - } - if (power < ((wattsFromResistance(1) * watt_gain) + watt_offset)) - return 1; - else - return max_resistance; -} - uint16_t proformbike::wattsFromResistance(resistance_t resistance) { if (currentCadence().value() == 0) return 0; - switch (resistance) { + switch ((resistance_t)resistance) { case 0: case 1: // -13.5 + 0.999x + 0.00993x² @@ -588,11 +565,7 @@ void proformbike::forceIncline(double incline) { void proformbike::innerWriteResistance() { if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -914,55 +887,19 @@ bool proformbike::inclinationAvailableByHardware() { return false; } +std::vector proformbike::bikeToPeloton({ 10,20,25,30,35,40,45,50,55,60,65,70,75,80,85,100 }); + +double proformbike::bikeResistanceToPeloton(double resistance) { + + auto r = this->resistanceLimits().clip(resistance); + + return bikeToPeloton[r-1]; +} + resistance_t proformbike::pelotonToBikeResistance(int pelotonResistance) { - if (pelotonResistance <= 10) { - return 1; - } - if (pelotonResistance <= 20) { - return 2; - } - if (pelotonResistance <= 25) { - return 3; - } - if (pelotonResistance <= 30) { - return 4; - } - if (pelotonResistance <= 35) { - return 5; - } - if (pelotonResistance <= 40) { - return 6; - } - if (pelotonResistance <= 45) { - return 7; - } - if (pelotonResistance <= 50) { - return 8; - } - if (pelotonResistance <= 55) { - return 9; - } - if (pelotonResistance <= 60) { - return 10; - } - if (pelotonResistance <= 65) { - return 11; - } - if (pelotonResistance <= 70) { - return 12; - } - if (pelotonResistance <= 75) { - return 13; - } - if (pelotonResistance <= 80) { - return 14; - } - if (pelotonResistance <= 85) { - return 15; - } - if (pelotonResistance <= 100) { - return 16; - } + for(int i=0; ibikeResistanceLimits = minmax(1,32); uint8_t initData1[] = {0xfe, 0x02, 0x08, 0x02}; uint8_t initData2[] = {0xff, 0x08, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x81, 0x87, @@ -1600,7 +1536,8 @@ void proformbike::btinit() { } else if (settings.value(QZSettings::proform_tdf_10, QZSettings::default_proform_tdf_10).toBool() || settings.value(QZSettings::proform_bike_PFEVEX71316_1, QZSettings::default_proform_bike_PFEVEX71316_1) .toBool()) { - max_resistance = 26; + this->bikeResistanceLimits = minmax(1,26); + uint8_t initData1[] = {0xfe, 0x02, 0x08, 0x02}; uint8_t initData2[] = {0xff, 0x08, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x81, 0x87, @@ -1737,7 +1674,7 @@ void proformbike::btinit() { writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (proform_bike_sb) { - max_resistance = 16; + this->bikeResistanceLimits = minmax(1,16); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x07, 0x01, 0x86, 0x64, 0x38, 0x1a, 0xfa, 0xe8, 0xcc, 0xa6, 0x9e}; @@ -1753,7 +1690,7 @@ void proformbike::btinit() { writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (nordictrack_gx_2_7) { - max_resistance = 20; + this->bikeResistanceLimits = minmax(1,20); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x04, 0x00, 0x9e, 0x84, 0x60, 0x4a, 0x32, 0x28, 0x04, 0xf6, 0xe6}; @@ -1769,7 +1706,7 @@ void proformbike::btinit() { writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (proform_cycle_trainer_400) { - max_resistance = 16; + this->bikeResistanceLimits = minmax(1,16); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x07, 0x01, 0x52, 0x74, 0x94, 0xb2, 0xde, 0x08, 0x20, 0x5e, 0x8a}; @@ -1785,7 +1722,7 @@ void proformbike::btinit() { writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (proform_cycle_trainer_300_ci) { - max_resistance = 16; + this->bikeResistanceLimits = minmax(1,16); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x04, 0x00, 0x10, 0xcc, 0x7a, 0x3e, 0xf4, 0xb8, 0x66, 0x3a, 0xf8}; @@ -1894,7 +1831,7 @@ void proformbike::btinit() { writeCharacteristic(noOpData22, sizeof(noOpData22), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (proform_bike_225_csx) { - max_resistance = 10; + this->bikeResistanceLimits = minmax(1,10); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x07, 0x01, 0xd2, 0x74, 0x14, 0xb2, 0x5e, 0x08, 0xa0, 0x5e, 0x0a}; uint8_t initData11[] = {0x01, 0x12, 0xbc, 0x6c, 0x1a, 0xc6, 0x90, 0x28, 0xe6, 0xa2, 0x64, 0x24, 0xe2, 0xae, 0x98, 0x50, 0x0e, 0xfa, 0xac, 0x9c}; uint8_t initData12[] = {0xff, 0x08, 0x4a, 0x36, 0x20, 0x98, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -1906,7 +1843,7 @@ void proformbike::btinit() { writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false); QThread::msleep(400); } else if (proform_hybrid_trainer_PFEL03815) { - max_resistance = 16; + this->bikeResistanceLimits = minmax(1,16); uint8_t initData10[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x28, 0x07, 0x28, 0x90, 0x04, 0x00, 0xb8, 0xac, 0x92, 0x8e, 0x7c, 0x78, 0x6e, 0x6a, 0x50}; uint8_t initData11[] = {0x01, 0x12, 0x54, 0x5a, 0x56, 0x54, 0x70, 0x76, 0x62, 0x68, diff --git a/src/devices/proformbike/proformbike.h b/src/devices/proformbike/proformbike.h index 2fe5c7ca6..faf3643d4 100644 --- a/src/devices/proformbike/proformbike.h +++ b/src/devices/proformbike/proformbike.h @@ -37,14 +37,21 @@ class proformbike : public bike { public: proformbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; - resistance_t maxResistance() override { return max_resistance; } + double bikeResistanceToPeloton(double resistance) override; + + minmax resistanceLimits() override {return this->bikeResistanceLimits;} bool inclinationAvailableByHardware() override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; + + private: - resistance_t max_resistance = 16; - uint16_t wattsFromResistance(resistance_t resistance); + /** + * @brief A mapping of peloton->(resistance-1) + */ + static std::vector bikeToPeloton; + double GetDistanceFromPacket(QByteArray packet); QTime GetElapsedFromPacket(QByteArray packet); void btinit(); @@ -71,6 +78,7 @@ class proformbike : public bike { QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); uint8_t firstStateChanged = 0; uint16_t m_watts = 0; + minmax bikeResistanceLimits{1,16}; bool initDone = false; bool initRequest = false; diff --git a/src/devices/proformtelnetbike/proformtelnetbike.cpp b/src/devices/proformtelnetbike/proformtelnetbike.cpp index 1802b3a58..ddc2f13d2 100644 --- a/src/devices/proformtelnetbike/proformtelnetbike.cpp +++ b/src/devices/proformtelnetbike/proformtelnetbike.cpp @@ -109,35 +109,13 @@ void proformtelnetbike::writeCharacteristic(uint8_t *data, uint8_t data_len, con loop.exec(); }*/ -resistance_t proformtelnetbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - QSettings settings; - - double watt_gain = settings.value(QZSettings::watt_gain, QZSettings::default_watt_gain).toDouble(); - double watt_offset = settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (((wattsFromResistance(i) * watt_gain) + watt_offset) <= power && - ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") - << ((wattsFromResistance(i) * watt_gain) + watt_offset) - << ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) << power; - return i; - } - } - if (power < ((wattsFromResistance(1) * watt_gain) + watt_offset)) - return 1; - else - return max_resistance; -} uint16_t proformtelnetbike::wattsFromResistance(resistance_t resistance) { if (currentCadence().value() == 0) return 0; - switch (resistance) { + switch ((resistance_t)resistance) { case 0: case 1: // -13.5 + 0.999x + 0.00993x² diff --git a/src/devices/proformtelnetbike/proformtelnetbike.h b/src/devices/proformtelnetbike/proformtelnetbike.h index 1c8d42e3f..717a5b55e 100644 --- a/src/devices/proformtelnetbike/proformtelnetbike.h +++ b/src/devices/proformtelnetbike/proformtelnetbike.h @@ -48,18 +48,17 @@ class proformtelnetbike : public bike { proformtelnetbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t resistanceFromPowerRequest(uint16_t power) override; - resistance_t maxResistance() override { return max_resistance; } + + minmax resistanceLimits() override {return minmax(0,100);} bool inclinationAvailableByHardware() override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: QTelnet telnet; - resistance_t max_resistance = 100; - resistance_t min_resistance = -20; double max_incline_supported = 20; void connectToDevice(); - uint16_t wattsFromResistance(resistance_t resistance); + double GetDistanceFromPacket(QByteArray packet); QTime GetElapsedFromPacket(QByteArray packet); void btinit(); diff --git a/src/devices/proformwifibike/proformwifibike.cpp b/src/devices/proformwifibike/proformwifibike.cpp index cc6eaebbc..e757b0546 100644 --- a/src/devices/proformwifibike/proformwifibike.cpp +++ b/src/devices/proformwifibike/proformwifibike.cpp @@ -112,35 +112,14 @@ void proformwifibike::writeCharacteristic(uint8_t *data, uint8_t data_len, const loop.exec(); }*/ -resistance_t proformwifibike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - QSettings settings; - - double watt_gain = settings.value(QZSettings::watt_gain, QZSettings::default_watt_gain).toDouble(); - double watt_offset = settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); - - for (resistance_t i = 1; i < max_resistance; i++) { - if (((wattsFromResistance(i) * watt_gain) + watt_offset) <= power && - ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") - << ((wattsFromResistance(i) * watt_gain) + watt_offset) - << ((wattsFromResistance(i + 1) * watt_gain) + watt_offset) << power; - return i; - } - } - if (power < ((wattsFromResistance(1) * watt_gain) + watt_offset)) - return 1; - else - return max_resistance; -} uint16_t proformwifibike::wattsFromResistance(resistance_t resistance) { if (currentCadence().value() == 0) return 0; - switch (resistance) { + switch ((resistance_t)resistance) { case 0: case 1: // -13.5 + 0.999x + 0.00993x² @@ -246,13 +225,8 @@ void proformwifibike::innerWriteResistance() { static QString last_mode = "MANUAL"; if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } else if (requestResistance < min_resistance) { - requestResistance = min_resistance; - } else if (requestResistance == 0) { - requestResistance = 1; - } + + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -349,55 +323,19 @@ void proformwifibike::update() { bool proformwifibike::inclinationAvailableByHardware() { return max_incline_supported > 0; } +std::vector proformwifibike::bikeToPeloton({ 10,20,25,30,35,40,45,50,55,60,65,70,75,80,85,100 }); + +double proformwifibike::bikeResistanceToPeloton(double resistance) { + + auto r = this->resistanceLimits().clip(resistance); + + return bikeToPeloton[r-1]; +} + resistance_t proformwifibike::pelotonToBikeResistance(int pelotonResistance) { - if (pelotonResistance <= 10) { - return 1; - } - if (pelotonResistance <= 20) { - return 2; - } - if (pelotonResistance <= 25) { - return 3; - } - if (pelotonResistance <= 30) { - return 4; - } - if (pelotonResistance <= 35) { - return 5; - } - if (pelotonResistance <= 40) { - return 6; - } - if (pelotonResistance <= 45) { - return 7; - } - if (pelotonResistance <= 50) { - return 8; - } - if (pelotonResistance <= 55) { - return 9; - } - if (pelotonResistance <= 60) { - return 10; - } - if (pelotonResistance <= 65) { - return 11; - } - if (pelotonResistance <= 70) { - return 12; - } - if (pelotonResistance <= 75) { - return 13; - } - if (pelotonResistance <= 80) { - return 14; - } - if (pelotonResistance <= 85) { - return 15; - } - if (pelotonResistance <= 100) { - return 16; - } + for(int i=0; i resistanceLimits() override {return minmax(0,100);} bool inclinationAvailableByHardware() override; bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; + private: + /** + * @brief A mapping of peloton->(resistance-1) + */ + static std::vector bikeToPeloton; QWebSocket websocket; - resistance_t max_resistance = 100; - resistance_t min_resistance = -20; double max_incline_supported = 20; void connectToDevice(); - uint16_t wattsFromResistance(resistance_t resistance); + double GetDistanceFromPacket(QByteArray packet); QTime GetElapsedFromPacket(QByteArray packet); void btinit(); diff --git a/src/devices/renphobike/renphobike.cpp b/src/devices/renphobike/renphobike.cpp index b84e10f29..7b2074b25 100644 --- a/src/devices/renphobike/renphobike.cpp +++ b/src/devices/renphobike/renphobike.cpp @@ -136,10 +136,7 @@ void renphobike::update() { // if zwift is connected we have to avoid to send resistance to the bike if ((virtualBike && !virtualBike->ftmsDeviceConnected()) || !virtualBike) { if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance == 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); lastRequestResistance = lastRawRequestedResistanceValue; debug("writing resistance " + QString::number(requestResistance)); @@ -688,7 +685,7 @@ void renphobike::deviceDiscovered(const QBluetoothDeviceInfo &device) { } resistance_t renphobike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance - 1; i++) { + for (resistance_t i = 1, max = this->resistanceLimits().max(); i < max - 1; i++) { if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) return i; } diff --git a/src/devices/renphobike/renphobike.h b/src/devices/renphobike/renphobike.h index 99874ba59..94756f0ef 100644 --- a/src/devices/renphobike/renphobike.h +++ b/src/devices/renphobike/renphobike.h @@ -37,13 +37,13 @@ class renphobike : public bike { public: renphobike(bool noWriteResistance, bool noHeartService); resistance_t pelotonToBikeResistance(int pelotonResistance) override; + double bikeResistanceToPeloton(double resistance) override; // uint8_t resistanceFromPowerRequest(uint16_t power); bool connected() override; - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return minmax(1,80);} private: - const resistance_t max_resistance = 80; - double bikeResistanceToPeloton(double resistance); + void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); void startDiscover(); diff --git a/src/devices/rower.h b/src/devices/rower.h index 048bee07e..6af81d786 100644 --- a/src/devices/rower.h +++ b/src/devices/rower.h @@ -37,8 +37,8 @@ class rower : public bluetoothdevice { void setPaused(bool p) override; QTime speedToPace(double Speed); void setGears(double d); - double gears(); - + double gears(); + minmax resistanceLimits() override { return minmax(0, this->maxResistance()); } public slots: void changeResistance(resistance_t res) override; virtual void changeCadence(int16_t cad); @@ -83,6 +83,8 @@ class rower : public bluetoothdevice { }; QList speedLast500mValues; + + virtual resistance_t maxResistance() { return 100; } }; #endif // ROWER_H diff --git a/src/devices/schwinn170bike/schwinn170bike.cpp b/src/devices/schwinn170bike/schwinn170bike.cpp index 820f7553f..43add61b1 100644 --- a/src/devices/schwinn170bike/schwinn170bike.cpp +++ b/src/devices/schwinn170bike/schwinn170bike.cpp @@ -28,6 +28,7 @@ schwinn170bike::schwinn170bike(bool noWriteResistance, bool noHeartService, uint this->bikeResistanceGain = bikeResistanceGain; this->bikeResistanceOffset = bikeResistanceOffset; initDone = false; + connect(refresh, &QTimer::timeout, this, &schwinn170bike::update); refresh->start(200ms); } @@ -80,11 +81,7 @@ void schwinn170bike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -508,6 +505,7 @@ resistance_t schwinn170bike::pelotonToBikeResistance(int pelotonResistance) { QSettings settings; bool schwinn_bike_resistance_v2 = settings.value(QZSettings::schwinn_bike_resistance_v2, QZSettings::default_schwinn_bike_resistance_v2).toBool(); + if (!schwinn_bike_resistance_v2) { if (pelotonResistance > 54) return pelotonResistance; @@ -524,26 +522,34 @@ resistance_t schwinn170bike::pelotonToBikeResistance(int pelotonResistance) { } } -uint16_t schwinn170bike::wattsFromResistance(double resistance) { + + +uint16_t schwinn170bike::wattsFromResistance(resistance_t resistance) { QSettings settings; - double ac = 0.01243107769; - double bc = 1.145964912; - double cc = -23.50977444; + constexpr double ac = 0.01243107769; + constexpr double bc = 1.145964912; + constexpr double cc = -23.50977444; - double ar = 0.1469553975; - double br = -5.841344538; - double cr = 97.62165482; + constexpr double ar = 0.1469553975; + constexpr double br = -5.841344538; + constexpr double cr = 97.62165482; + + constexpr double brSq = br*br; + + const double peloton_gain = settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble(); + const double peloton_offset = settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + const double cadence = this->Cadence.value(), cadenceSq = cadence*cadence; for (uint16_t i = 1; i < 2000; i += 5) { double res = - (((sqrt(pow(br, 2.0) - + (((sqrt(brSq - 4.0 * ar * - (cr - ((double)i * 132.0 / (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + (cr - ((double)i * 132.0 / (ac * cadenceSq + bc * cadence + cc)))) - br) / (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + peloton_gain) + + peloton_offset; if (!isnan(res) && res >= resistance) { return i; diff --git a/src/devices/schwinn170bike/schwinn170bike.h b/src/devices/schwinn170bike/schwinn170bike.h index 27bcce285..ff3e9d8bd 100644 --- a/src/devices/schwinn170bike/schwinn170bike.h +++ b/src/devices/schwinn170bike/schwinn170bike.h @@ -42,13 +42,14 @@ class schwinn170bike : public bike { double bikeResistanceGain); resistance_t pelotonToBikeResistance(int pelotonResistance) override; bool ergManagedBySS2K() override { return true; } - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return minmax(1,100);} bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: void writeCharacteristic(QLowEnergyService *service, QLowEnergyCharacteristic characteristic, uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); - uint16_t wattsFromResistance(double resistance); + void startDiscover(); uint16_t watts() override; @@ -67,7 +68,6 @@ class schwinn170bike : public bike { bool noWriteResistance = false; bool noHeartService = false; - const resistance_t max_resistance = 100; uint8_t bikeResistanceOffset = 4; double bikeResistanceGain = 1.0; diff --git a/src/devices/schwinnic4bike/schwinnic4bike.cpp b/src/devices/schwinnic4bike/schwinnic4bike.cpp index 72e1d928e..ade4ae68f 100644 --- a/src/devices/schwinnic4bike/schwinnic4bike.cpp +++ b/src/devices/schwinnic4bike/schwinnic4bike.cpp @@ -81,11 +81,7 @@ void schwinnic4bike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -590,7 +586,7 @@ resistance_t schwinnic4bike::pelotonToBikeResistance(int pelotonResistance) { } } -uint16_t schwinnic4bike::wattsFromResistance(double resistance) { +uint16_t schwinnic4bike::wattsFromResistance(resistance_t resistance) { QSettings settings; double ac = 0.01243107769; @@ -601,15 +597,19 @@ uint16_t schwinnic4bike::wattsFromResistance(double resistance) { double br = -5.841344538; double cr = 97.62165482; + const double peloton_gain = settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble(); + const double peloton_offset = settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + const double cadence = this->Cadence.value(), cadenceSq = cadence*cadence; + for (uint16_t i = 1; i < 2000; i += 5) { double res = (((sqrt(pow(br, 2.0) - 4.0 * ar * - (cr - ((double)i * 132.0 / (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + (cr - ((double)i * 132.0 / (ac * cadenceSq + bc * cadence + cc)))) - br) / (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + peloton_gain) + + peloton_offset; if (!isnan(res) && res >= resistance) { return i; diff --git a/src/devices/schwinnic4bike/schwinnic4bike.h b/src/devices/schwinnic4bike/schwinnic4bike.h index 707b15075..f53b9ccf9 100644 --- a/src/devices/schwinnic4bike/schwinnic4bike.h +++ b/src/devices/schwinnic4bike/schwinnic4bike.h @@ -40,13 +40,14 @@ class schwinnic4bike : public bike { schwinnic4bike(bool noWriteResistance, bool noHeartService); resistance_t pelotonToBikeResistance(int pelotonResistance) override; bool ergManagedBySS2K() override { return true; } - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return minmax(1,100);} bool connected() override; + uint16_t wattsFromResistance(resistance_t resistance) override; private: void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); - uint16_t wattsFromResistance(double resistance); + void startDiscover(); uint16_t watts() override; @@ -66,8 +67,6 @@ class schwinnic4bike : public bike { bool noWriteResistance = false; bool noHeartService = false; - const resistance_t max_resistance = 100; - metric ResistanceFromFTMSAccessory; #ifdef Q_OS_IOS diff --git a/src/devices/skandikawiribike/skandikawiribike.cpp b/src/devices/skandikawiribike/skandikawiribike.cpp index a1a3753c6..b56e50dbc 100644 --- a/src/devices/skandikawiribike/skandikawiribike.cpp +++ b/src/devices/skandikawiribike/skandikawiribike.cpp @@ -102,11 +102,7 @@ void skandikawiribike::update() { } if (requestResistance != -1) { - if (requestResistance > 32) { - requestResistance = 32; - } else if (requestResistance < 1) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/skandikawiribike/skandikawiribike.h b/src/devices/skandikawiribike/skandikawiribike.h index e7809e961..ee5d33e3b 100644 --- a/src/devices/skandikawiribike/skandikawiribike.h +++ b/src/devices/skandikawiribike/skandikawiribike.h @@ -39,6 +39,7 @@ class skandikawiribike : public bike { double bikeResistanceGain); ~skandikawiribike(); bool connected() override; + minmax resistanceLimits() override {return minmax(1,32);} private: double GetSpeedFromPacket(const QByteArray &packet); diff --git a/src/devices/smartspin2k/smartspin2k.cpp b/src/devices/smartspin2k/smartspin2k.cpp index 2c2cdd7e3..3404735c5 100644 --- a/src/devices/smartspin2k/smartspin2k.cpp +++ b/src/devices/smartspin2k/smartspin2k.cpp @@ -22,7 +22,7 @@ smartspin2k::smartspin2k(bool noWriteResistance, bool noHeartService, resistance QSettings settings; m_watt.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); - this->max_resistance = max_resistance; + this->bikeResistanceLimits = minmax(1,max_resistance); this->parentDevice = parentDevice; refresh = new QTimer(this); this->noWriteResistance = noWriteResistance; @@ -298,12 +298,7 @@ void smartspin2k::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } // TODO, use the bluetooth value - else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); // TODO, use the bluetooth value if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/smartspin2k/smartspin2k.h b/src/devices/smartspin2k/smartspin2k.h index f25c60640..3bfa72f7f 100644 --- a/src/devices/smartspin2k/smartspin2k.h +++ b/src/devices/smartspin2k/smartspin2k.h @@ -42,6 +42,8 @@ class smartspin2k : public bike { smartspin2k(bool noWriteResistance, bool noHeartService, resistance_t max_resistance, bike *parentDevice); bool connected() override; + minmax resistanceLimits() override {return this->bikeResistanceLimits;} + private: #define max_calibration_samples 4 void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, @@ -67,6 +69,7 @@ class smartspin2k : public bike { QByteArray lastPacket; QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); uint8_t firstStateChanged = 0; + minmax bikeResistanceLimits {1,100}; bool initDone = false; bool initRequest = false; @@ -79,7 +82,6 @@ class smartspin2k : public bike { resistance_t lastResistance; resistance_t lastRequestResistance; - resistance_t max_resistance; double slope = 0.0; double intercept = 0.0; diff --git a/src/devices/snodebike/snodebike.cpp b/src/devices/snodebike/snodebike.cpp index 19760df18..cadd39f53 100644 --- a/src/devices/snodebike/snodebike.cpp +++ b/src/devices/snodebike/snodebike.cpp @@ -80,11 +80,7 @@ void snodebike::update() { } if (requestResistance != -1) { - if (requestResistance > 15) { - requestResistance = 15; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/snodebike/snodebike.h b/src/devices/snodebike/snodebike.h index fb29922b8..3cd5fa2fa 100644 --- a/src/devices/snodebike/snodebike.h +++ b/src/devices/snodebike/snodebike.h @@ -39,6 +39,7 @@ class snodebike : public bike { public: snodebike(bool noWriteResistance, bool noHeartService); bool connected() override; + minmax resistanceLimits() override {return minmax(1,15);} private: void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, diff --git a/src/devices/solebike/solebike.cpp b/src/devices/solebike/solebike.cpp index acb9af093..07b117e0e 100644 --- a/src/devices/solebike/solebike.cpp +++ b/src/devices/solebike/solebike.cpp @@ -167,10 +167,7 @@ void solebike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -198,17 +195,6 @@ void solebike::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); } -resistance_t solebike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; -} double solebike::bikeResistanceToPeloton(double resistance) { // 0,0097x3 - 0,4972x2 + 10,126x - 37,08 diff --git a/src/devices/solebike/solebike.h b/src/devices/solebike/solebike.h index 29772889b..614347d42 100644 --- a/src/devices/solebike/solebike.h +++ b/src/devices/solebike/solebike.h @@ -36,14 +36,12 @@ class solebike : public bike { Q_OBJECT public: solebike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } + minmax resistanceLimits() override {return minmax(1,40);} bool connected() override; private: bool r92 = false; - const resistance_t max_resistance = 40; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; double GetDistanceFromPacket(const QByteArray &packet); double GetSpeedFromPacket(const QByteArray &packet); double GetWattFromPacket(const QByteArray &packet); diff --git a/src/devices/sportsplusbike/sportsplusbike.cpp b/src/devices/sportsplusbike/sportsplusbike.cpp index 3b32ca1d3..63eb956d7 100644 --- a/src/devices/sportsplusbike/sportsplusbike.cpp +++ b/src/devices/sportsplusbike/sportsplusbike.cpp @@ -71,7 +71,11 @@ void sportsplusbike::forceResistance(resistance_t requestResistance) { } resistance_t sportsplusbike::pelotonToBikeResistance(int pelotonResistance) { - return (pelotonResistance * max_resistance) / 100; + return (pelotonResistance * this->resistanceLimits().max()) / 100; +} + +double sportsplusbike::bikeResistanceToPeloton(double resistance) { + return (int)(1+resistance * 100.0/this->resistanceLimits().max()); } void sportsplusbike::update() { @@ -103,12 +107,9 @@ void sportsplusbike::update() { QSettings settings; uint8_t noOpData[] = {0x20, 0x01, 0x09, 0x00, 0x2a}; - if (requestResistance < 0) { - requestResistance = 0; - } - if (requestResistance > max_resistance) { - requestResistance = max_resistance; - } + + requestResistance = this->resistanceLimits().clip(requestResistance); + noOpData[2] = requestResistance; noOpData[4] = (0x21 + requestResistance); writeCharacteristic((uint8_t *)noOpData, sizeof(noOpData), QStringLiteral("noOp"), false, true); @@ -521,7 +522,7 @@ void sportsplusbike::controllerStateChanged(QLowEnergyController::ControllerStat } } -uint16_t sportsplusbike::wattsFromResistance(double resistance) { +uint16_t sportsplusbike::wattsFromResistance(resistance_t resistance) { const int wattTableFirstDimension = 24; const int wattTableSecondDimension = 6; double wattTable[wattTableFirstDimension][wattTableSecondDimension] = { diff --git a/src/devices/sportsplusbike/sportsplusbike.h b/src/devices/sportsplusbike/sportsplusbike.h index b9436a7b7..b6460ccca 100644 --- a/src/devices/sportsplusbike/sportsplusbike.h +++ b/src/devices/sportsplusbike/sportsplusbike.h @@ -33,8 +33,12 @@ class sportsplusbike : public bike { public: sportsplusbike(bool noWriteResistance, bool noHeartService); resistance_t pelotonToBikeResistance(int pelotonResistance) override; + double bikeResistanceToPeloton(double resistance) override; bool connected() override; + minmax resistanceLimits() override {return minmax(0,24);} + uint16_t wattsFromResistance(resistance_t resistance) override; + private: double GetSpeedFromPacket(const QByteArray &packet); double GetKcalFromPacket(const QByteArray &packet); @@ -45,7 +49,7 @@ class sportsplusbike : public bike { void btinit(bool startTape); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log, bool wait_for_response); - uint16_t wattsFromResistance(double resistance); + void startDiscover(); uint16_t watts() override; double GetWattFromPacket(const QByteArray &packet); @@ -75,8 +79,6 @@ class sportsplusbike : public bike { bool carefitness_bike = false; - const resistance_t max_resistance = 24; - signals: void disconnected(); void debug(QString string); diff --git a/src/devices/sportstechbike/sportstechbike.cpp b/src/devices/sportstechbike/sportstechbike.cpp index 361a68391..76d0ea2ab 100644 --- a/src/devices/sportstechbike/sportstechbike.cpp +++ b/src/devices/sportstechbike/sportstechbike.cpp @@ -99,12 +99,7 @@ void sportstechbike::update() { QSettings settings; uint8_t noOpData[] = {0xf2, 0xc3, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbe}; - if (requestResistance < 0) { - requestResistance = 0; - } - if (requestResistance > 23) { - requestResistance = 23; - } + requestResistance = this->resistanceLimits().clip(requestResistance); noOpData[4] = requestResistance; noOpData[10] += requestResistance; writeCharacteristic((uint8_t *)noOpData, sizeof(noOpData), QStringLiteral("noOp"), false, true); @@ -418,7 +413,7 @@ void sportstechbike::controllerStateChanged(QLowEnergyController::ControllerStat } } -uint16_t sportstechbike::wattsFromResistance(double resistance) { +uint16_t sportstechbike::wattsFromResistance(resistance_t resistance) { // Coefficients from the polynomial regression double intercept = 14.4968; double b1 = -4.1878; @@ -439,21 +434,3 @@ uint16_t sportstechbike::wattsFromResistance(double resistance) { return power; } -resistance_t sportstechbike::resistanceFromPowerRequest(uint16_t power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - - if (Cadence.value() == 0) - return 1; - - for (resistance_t i = 1; i < maxResistance(); i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return maxResistance(); -} \ No newline at end of file diff --git a/src/devices/sportstechbike/sportstechbike.h b/src/devices/sportstechbike/sportstechbike.h index d973805c1..8e79fc059 100644 --- a/src/devices/sportstechbike/sportstechbike.h +++ b/src/devices/sportstechbike/sportstechbike.h @@ -32,16 +32,15 @@ class sportstechbike : public bike { public: sportstechbike(bool noWriteResistance, bool noHeartService); bool connected() override; - resistance_t maxResistance() override { return 24; } - resistance_t resistanceFromPowerRequest(uint16_t power) override; - + minmax resistanceLimits() override {return minmax(0,23);} + uint16_t wattsFromResistance(resistance_t resistance) override; private: double GetSpeedFromPacket(const QByteArray &packet); double GetResistanceFromPacket(const QByteArray &packet); double GetKcalFromPacket(const QByteArray &packet); double GetDistanceFromPacket(QByteArray packet); uint16_t GetElapsedFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); + void forceResistance(resistance_t requestResistance); void updateDisplay(uint16_t elapsed); void btinit(bool startTape); diff --git a/src/devices/stagesbike/stagesbike.cpp b/src/devices/stagesbike/stagesbike.cpp index 9a86d207e..5491bd975 100644 --- a/src/devices/stagesbike/stagesbike.cpp +++ b/src/devices/stagesbike/stagesbike.cpp @@ -82,11 +82,7 @@ void stagesbike::update() { } if (requestResistance != -1) { - if (requestResistance > 100) { - requestResistance = 100; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -134,7 +130,7 @@ resistance_t stagesbike::pelotonToBikeResistance(int pelotonResistance) { } } -uint16_t stagesbike::wattsFromResistance(double resistance) { +uint16_t stagesbike::wattsFromResistance(resistance_t resistance) { QSettings settings; double ac = 0.01243107769; @@ -145,15 +141,19 @@ uint16_t stagesbike::wattsFromResistance(double resistance) { double br = -5.841344538; double cr = 97.62165482; + const double peloton_gain = settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble(); + const double peloton_offset = settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + const double cadence = this->Cadence.value(), cadenceSq = cadence*cadence; + for (uint16_t i = 1; i < 2000; i += 5) { double res = (((sqrt(pow(br, 2.0) - 4.0 * ar * - (cr - ((double)i * 132.0 / (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + (cr - ((double)i * 132.0 / (ac * cadenceSq + bc * cadence + cc)))) - br) / (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + peloton_gain) + + peloton_offset; if (!isnan(res) && res >= resistance) { return i; diff --git a/src/devices/stagesbike/stagesbike.h b/src/devices/stagesbike/stagesbike.h index 71fed7976..9b2857cdf 100644 --- a/src/devices/stagesbike/stagesbike.h +++ b/src/devices/stagesbike/stagesbike.h @@ -38,13 +38,14 @@ class stagesbike : public bike { stagesbike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice); resistance_t pelotonToBikeResistance(int pelotonResistance) override; bool connected() override; - resistance_t maxResistance() override { return 100; } + minmax resistanceLimits() override {return minmax(1,100);} bool ergManagedBySS2K() override { return true; } + uint16_t wattsFromResistance(resistance_t resistance) override; private: void writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); - uint16_t wattsFromResistance(double resistance); + metric ResistanceFromFTMSAccessory; uint64_t ResistanceFromFTMSAccessoryLastTime = 0; void startDiscover(); diff --git a/src/devices/tacxneo2/tacxneo2.cpp b/src/devices/tacxneo2/tacxneo2.cpp index f00edf42d..d025c795b 100644 --- a/src/devices/tacxneo2/tacxneo2.cpp +++ b/src/devices/tacxneo2/tacxneo2.cpp @@ -586,18 +586,6 @@ void tacxneo2::controllerStateChanged(QLowEnergyController::ControllerState stat } } -resistance_t tacxneo2::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 0; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) > pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 0; - else - return max_resistance; -} - double tacxneo2::bikeResistanceToPeloton(double resistance) { QSettings settings; bool tacx_neo2_peloton = diff --git a/src/devices/tacxneo2/tacxneo2.h b/src/devices/tacxneo2/tacxneo2.h index 4dd512e51..4a62e501f 100644 --- a/src/devices/tacxneo2/tacxneo2.h +++ b/src/devices/tacxneo2/tacxneo2.h @@ -38,7 +38,8 @@ class tacxneo2 : public bike { tacxneo2(bool noWriteResistance, bool noHeartService); void changePower(int32_t power) override; bool connected() override; - resistance_t pelotonToBikeResistance(int pelotonResistance) override; + + minmax resistanceLimits() override {return minmax(0,100);} private: void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, @@ -46,12 +47,10 @@ class tacxneo2 : public bike { void startDiscover(); void forceInclination(double inclination); uint16_t watts() override; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; QTimer *refresh; - const int max_resistance = 100; - QList gattCommunicationChannelService; QLowEnergyCharacteristic gattWriteCharControlPointId; QLowEnergyCharacteristic gattWriteCharCustomId; diff --git a/src/devices/trxappgateusbbike/trxappgateusbbike.cpp b/src/devices/trxappgateusbbike/trxappgateusbbike.cpp index 9f5f77628..b7b1f0abb 100644 --- a/src/devices/trxappgateusbbike/trxappgateusbbike.cpp +++ b/src/devices/trxappgateusbbike/trxappgateusbbike.cpp @@ -176,11 +176,8 @@ void trxappgateusbbike::update() { writeCharacteristic((uint8_t *)noOpData, sizeof(noOpData), QStringLiteral("noOp"), false, true); } if (requestResistance != -1) { - if (requestResistance > 32) { - requestResistance = 32; - } else if (requestResistance < 1) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); + if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); @@ -1159,7 +1156,7 @@ void trxappgateusbbike::controllerStateChanged(QLowEnergyController::ControllerS } } -uint16_t trxappgateusbbike::wattsFromResistance(double resistance) { +uint16_t trxappgateusbbike::wattsFromResistance(resistance_t resistance) { QSettings settings; bool toorx_srx_3500 = settings.value(QZSettings::toorx_srx_3500, QZSettings::default_toorx_srx_3500).toBool(); if(toorx_srx_3500) { @@ -1177,27 +1174,4 @@ uint16_t trxappgateusbbike::wattsFromResistance(double resistance) { } } -resistance_t trxappgateusbbike::resistanceFromPowerRequest(uint16_t power) { - //QSettings settings; - //bool toorx_srx_3500 = settings.value(QZSettings::toorx_srx_3500, QZSettings::default_toorx_srx_3500).toBool(); - /*if(toorx_srx_3500)*/ { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << Cadence.value(); - if (Cadence.value() == 0) - return 1; - - for (resistance_t i = 1; i < maxResistance(); i++) { - if (wattsFromResistance(i) <= power && wattsFromResistance(i + 1) >= power) { - qDebug() << QStringLiteral("resistanceFromPowerRequest") << wattsFromResistance(i) - << wattsFromResistance(i + 1) << power; - return i; - } - } - if (power < wattsFromResistance(1)) - return 1; - else - return maxResistance(); - } /*else { - return power / 10; - }*/ -} diff --git a/src/devices/trxappgateusbbike/trxappgateusbbike.h b/src/devices/trxappgateusbbike/trxappgateusbbike.h index 9401d5e41..7bdf03672 100644 --- a/src/devices/trxappgateusbbike/trxappgateusbbike.h +++ b/src/devices/trxappgateusbbike/trxappgateusbbike.h @@ -38,9 +38,8 @@ class trxappgateusbbike : public bike { trxappgateusbbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); bool connected() override; - resistance_t maxResistance() override { return 32; } - resistance_t resistanceFromPowerRequest(uint16_t power) override; - + minmax resistanceLimits() override {return minmax(1,32);} + uint16_t wattsFromResistance(resistance_t resistance) override; private: double GetSpeedFromPacket(const QByteArray &packet); double GetResistanceFromPacket(const QByteArray &packet); @@ -57,7 +56,6 @@ class trxappgateusbbike : public bike { double GetWattFromPacket(const QByteArray &packet); double GetWattFromPacketFytter(const QByteArray &packet); double GetCadenceFromPacket(const QByteArray &packet); - uint16_t wattsFromResistance(double resistance); QTimer *refresh; diff --git a/src/devices/ultrasportbike/ultrasportbike.cpp b/src/devices/ultrasportbike/ultrasportbike.cpp index c38e4761b..f8c638f74 100644 --- a/src/devices/ultrasportbike/ultrasportbike.cpp +++ b/src/devices/ultrasportbike/ultrasportbike.cpp @@ -107,10 +107,7 @@ void ultrasportbike::update() { } if (requestResistance != -1) { - if (requestResistance > max_resistance) - requestResistance = max_resistance; - else if (requestResistance <= 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); @@ -137,17 +134,6 @@ void ultrasportbike::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); } -resistance_t ultrasportbike::pelotonToBikeResistance(int pelotonResistance) { - for (resistance_t i = 1; i < max_resistance; i++) { - if (bikeResistanceToPeloton(i) <= pelotonResistance && bikeResistanceToPeloton(i + 1) >= pelotonResistance) { - return i; - } - } - if (pelotonResistance < bikeResistanceToPeloton(1)) - return 1; - else - return max_resistance; -} double ultrasportbike::bikeResistanceToPeloton(double resistance) { // 0,0097x3 - 0,4972x2 + 10,126x - 37,08 diff --git a/src/devices/ultrasportbike/ultrasportbike.h b/src/devices/ultrasportbike/ultrasportbike.h index 091c41980..894928322 100644 --- a/src/devices/ultrasportbike/ultrasportbike.h +++ b/src/devices/ultrasportbike/ultrasportbike.h @@ -38,14 +38,13 @@ class ultrasportbike : public bike { public: ultrasportbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); - resistance_t pelotonToBikeResistance(int pelotonResistance) override; - resistance_t maxResistance() override { return max_resistance; } + + minmax resistanceLimits() override {return minmax(1,40);} bool connected() override; private: bool r92 = false; - const resistance_t max_resistance = 40; - double bikeResistanceToPeloton(double resistance); + double bikeResistanceToPeloton(double resistance) override; double GetWattFromPacket(const QByteArray &packet); void btinit(); void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, diff --git a/src/devices/wahookickrsnapbike/wahookickrsnapbike.cpp b/src/devices/wahookickrsnapbike/wahookickrsnapbike.cpp index 69bba6a91..1983d3c8c 100644 --- a/src/devices/wahookickrsnapbike/wahookickrsnapbike.cpp +++ b/src/devices/wahookickrsnapbike/wahookickrsnapbike.cpp @@ -236,11 +236,7 @@ void wahookickrsnapbike::update() { } lastGearValue = gears(); } else if (requestResistance != -1 && KICKR_BIKE == false) { - if (requestResistance > 100) { - requestResistance = 100; - } else if (requestResistance == 0) { - requestResistance = 1; - } + requestResistance = this->resistanceLimits().clip(requestResistance); auto virtualBike = this->VirtualBike(); if (requestResistance != currentResistance().value() && @@ -304,7 +300,7 @@ resistance_t wahookickrsnapbike::pelotonToBikeResistance(int pelotonResistance) } } -uint16_t wahookickrsnapbike::wattsFromResistance(double resistance) { +uint16_t wahookickrsnapbike::wattsFromResistance(resistance_t resistance) { QSettings settings; double ac = 0.01243107769; @@ -315,15 +311,19 @@ uint16_t wahookickrsnapbike::wattsFromResistance(double resistance) { double br = -5.841344538; double cr = 97.62165482; + const double peloton_gain = settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble(); + const double peloton_offset = settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + const double cadence = this->Cadence.value(), cadenceSq = cadence*cadence; + for (uint16_t i = 1; i < 2000; i += 5) { double res = (((sqrt(pow(br, 2.0) - 4.0 * ar * - (cr - ((double)i * 132.0 / (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + (cr - ((double)i * 132.0 / (ac * cadenceSq + bc * cadence + cc)))) - br) / (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + peloton_gain) + + peloton_offset; if (!isnan(res) && res >= resistance) { return i; @@ -824,4 +824,4 @@ void wahookickrsnapbike::inclinationChanged(double grade, double percentage) { bool wahookickrsnapbike::inclinationAvailableByHardware() { return KICKR_BIKE; -} \ No newline at end of file +} diff --git a/src/devices/wahookickrsnapbike/wahookickrsnapbike.h b/src/devices/wahookickrsnapbike/wahookickrsnapbike.h index 3d4ae1f53..65c5bcc05 100644 --- a/src/devices/wahookickrsnapbike/wahookickrsnapbike.h +++ b/src/devices/wahookickrsnapbike/wahookickrsnapbike.h @@ -40,7 +40,7 @@ class wahookickrsnapbike : public bike { double bikeResistanceGain); resistance_t pelotonToBikeResistance(int pelotonResistance) override; bool connected() override; - resistance_t maxResistance() override { return 100; } + minmax resistanceLimits() override {return minmax(1,100);} bool inclinationAvailableByHardware() override; enum OperationCode : uint8_t { @@ -56,6 +56,8 @@ class wahookickrsnapbike : public bike { _setWheelCircumference = 72, }; + uint16_t wattsFromResistance(resistance_t resistance) override; + private: QByteArray unlockCommand(); QByteArray setResistanceMode(double resistance); @@ -70,7 +72,7 @@ class wahookickrsnapbike : public bike { bool writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false, bool wait_for_response = false); - uint16_t wattsFromResistance(double resistance); + metric ResistanceFromFTMSAccessory; void startDiscover(); uint16_t watts() override; diff --git a/src/devices/yesoulbike/yesoulbike.cpp b/src/devices/yesoulbike/yesoulbike.cpp index 27032d171..f34de6673 100644 --- a/src/devices/yesoulbike/yesoulbike.cpp +++ b/src/devices/yesoulbike/yesoulbike.cpp @@ -78,10 +78,7 @@ void yesoulbike::update() { } if (requestResistance != -1) { - if (requestResistance > 15) - requestResistance = 15; - else if (requestResistance == 0) - requestResistance = 1; + requestResistance = this->resistanceLimits().clip(requestResistance); if (requestResistance != currentResistance().value()) { emit debug(QStringLiteral("writing resistance ") + QString::number(requestResistance)); diff --git a/src/devices/yesoulbike/yesoulbike.h b/src/devices/yesoulbike/yesoulbike.h index 1090f01d5..84b54d47a 100644 --- a/src/devices/yesoulbike/yesoulbike.h +++ b/src/devices/yesoulbike/yesoulbike.h @@ -44,6 +44,8 @@ class yesoulbike : public bike { double bikeResistanceGain); bool connected() override; + minmax resistanceLimits() override {return minmax(1,15);} + private: double GetDistanceFromPacket(const QByteArray &packet); QTime GetElapsedFromPacket(QByteArray packet); diff --git a/src/ergtable.h b/src/ergtable.h index 2c6161513..c4ebd25d0 100644 --- a/src/ergtable.h +++ b/src/ergtable.h @@ -5,7 +5,7 @@ #include #include #include -#include > +#include #include "qzsettings.h" struct ergDataPoint { diff --git a/src/minmax.h b/src/minmax.h new file mode 100644 index 000000000..f4fa49642 --- /dev/null +++ b/src/minmax.h @@ -0,0 +1,26 @@ +#ifndef MINMAX_H +#define MINMAX_H + +template +struct minmax { + private: + T _max, _min; + public: + const T max() { return _max; } + const T min() { return _min; } + + explicit minmax(const T min, const T max) : _max(max), _min(min) {} + + T clip(const T value) const { + T result = value; + if(value<_min) result=_min; + else if(value>_max) result=_max; + return result; + } + + bool contains(const T value) const { + return value>=_min && value<=_max; + } +}; + +#endif diff --git a/src/qdomyos-zwift.pri b/src/qdomyos-zwift.pri index e6552133d..d148bb67e 100755 --- a/src/qdomyos-zwift.pri +++ b/src/qdomyos-zwift.pri @@ -290,6 +290,7 @@ HEADERS += \ $$PWD/devices/focustreadmill/focustreadmill.h \ $$PWD/devices/trxappgateusbelliptical/trxappgateusbelliptical.h \ $$PWD/ergtable.h \ + $$PWD/minmax.h \ QTelnet.h \ devices/bkoolbike/bkoolbike.h \ devices/csaferower/csafe.h \ diff --git a/tst/Devices/ApexBike/apexbiketestdata.h b/tst/Devices/ApexBike/apexbiketestdata.h index b37e1edb0..390fb7147 100644 --- a/tst/Devices/ApexBike/apexbiketestdata.h +++ b/tst/Devices/ApexBike/apexbiketestdata.h @@ -1,10 +1,13 @@ #pragma once -#include "Devices/Bike/biketestdata.h".h" +#include "Devices/Bike/biketestdata.h" #include "devices/apexbike/apexbike.h" class ApexBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new apexbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: ApexBikeTestData() : BikeTestData("Apex Bike") { this->addDeviceName("WLT8266BM", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/Bike/biketestdata.h b/tst/Devices/Bike/biketestdata.h index ffaea9520..333ec6c46 100644 --- a/tst/Devices/Bike/biketestdata.h +++ b/tst/Devices/Bike/biketestdata.h @@ -3,7 +3,21 @@ #include "Devices/bluetoothdevicetestdata.h" #include "devices/bike.h" +class BikeOptions { +public: + double resistanceGain=1.0, resistanceOffset=0.0; + bool noResistance=false, noHeartService = false, noVirtualDevice = false; + +}; + class BikeTestData : public BluetoothDeviceTestData { +protected: + /** + * @brief Template function called from createInstance to create an instance of the device class. + * @param options + * @return + */ + virtual bike* doCreateInstance(const BikeOptions& options) =0; public: BikeTestData(std::string deviceName) : BluetoothDeviceTestData(deviceName) {} @@ -15,5 +29,18 @@ class BikeTestData : public BluetoothDeviceTestData { bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override { return dynamic_cast(detectedDevice)!=nullptr; } + + /** + * @brief (Potentially amongst other things) Calls a protected function to create an instance of the device class. + * @param options + * @return + */ + bike* createInstance(const BikeOptions& options) { + // potentially validate or alter the options + auto result = this->doCreateInstance(options); + + // potentially adjust the device object (e.g. connect signals and slots) + return result; + } }; diff --git a/tst/Devices/BkoolBike/bkoolbiketestdata.h b/tst/Devices/BkoolBike/bkoolbiketestdata.h index 96f7163d5..c1bfc335c 100644 --- a/tst/Devices/BkoolBike/bkoolbiketestdata.h +++ b/tst/Devices/BkoolBike/bkoolbiketestdata.h @@ -1,12 +1,15 @@ #pragma once -#include "Devices/bluetoothdevicetestdata.h" +#include "Devices/Bike/biketestdata.h" #include "devices/bkoolbike/bkoolbike.h" -class BkoolBikeTestData : public BluetoothDeviceTestData { - +class BkoolBikeTestData : public BikeTestData { +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new bkoolbike(options.noResistance, options.noHeartService); + } public: - BkoolBikeTestData() : BluetoothDeviceTestData("Bkool Bike") { + BkoolBikeTestData() : BikeTestData("Bkool Bike") { this->addDeviceName("BKOOLSMARTPRO", comparison::StartsWithIgnoreCase); } diff --git a/tst/Devices/CSCBike/cscbiketestdata.h b/tst/Devices/CSCBike/cscbiketestdata.h index c24db03df..abdaa1265 100644 --- a/tst/Devices/CSCBike/cscbiketestdata.h +++ b/tst/Devices/CSCBike/cscbiketestdata.h @@ -6,6 +6,11 @@ class CSCBikeTestData : public BikeTestData { protected: QString cscBikeName; + + + bike* doCreateInstance(const BikeOptions& options) override { + return new cscbike(options.noResistance, options.noHeartService, options.noVirtualDevice); + } public: CSCBikeTestData(std::string testName) : BikeTestData(testName) { this->cscBikeName = "CyclingSpeedCadenceBike-"; diff --git a/tst/Devices/Chronobike/chronobiketestdata.h b/tst/Devices/Chronobike/chronobiketestdata.h index 40fe1f3ac..a43cda3bb 100644 --- a/tst/Devices/Chronobike/chronobiketestdata.h +++ b/tst/Devices/Chronobike/chronobiketestdata.h @@ -4,7 +4,10 @@ #include "devices/chronobike/chronobike.h" class ChronobikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new chronobike(options.noResistance, options.noHeartService); + } public: ChronobikeTestData() : BikeTestData("Chronobike") { this->addDeviceName("CHRONO ", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/CompuTrainer/computrainertestdata.h b/tst/Devices/CompuTrainer/computrainertestdata.h index a93f537ca..b6d64c116 100644 --- a/tst/Devices/CompuTrainer/computrainertestdata.h +++ b/tst/Devices/CompuTrainer/computrainertestdata.h @@ -5,6 +5,10 @@ class CompuTrainerTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new computrainerbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } + bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override { info.computrainer_serial_port = enable ? "X":QString(); return true; diff --git a/tst/Devices/DomyosBike/domyosbiketestdata.h b/tst/Devices/DomyosBike/domyosbiketestdata.h index ba91cc8e8..031765331 100644 --- a/tst/Devices/DomyosBike/domyosbiketestdata.h +++ b/tst/Devices/DomyosBike/domyosbiketestdata.h @@ -4,7 +4,10 @@ #include "devices/domyosbike/domyosbike.h" class DomyosBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new domyosbike(options.noResistance, options.noHeartService, false, options.resistanceOffset, options.resistanceGain); + } public: DomyosBikeTestData() : BikeTestData("Domyos Bike") { diff --git a/tst/Devices/EchelonConnectSportBike/echelonconnectsportbiketestdata.h b/tst/Devices/EchelonConnectSportBike/echelonconnectsportbiketestdata.h index 9e08797ff..2ff101dde 100644 --- a/tst/Devices/EchelonConnectSportBike/echelonconnectsportbiketestdata.h +++ b/tst/Devices/EchelonConnectSportBike/echelonconnectsportbiketestdata.h @@ -6,7 +6,10 @@ #include "devices/echelonconnectsport/echelonconnectsport.h" class EchelonConnectSportBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new echelonconnectsport(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: EchelonConnectSportBikeTestData() : BikeTestData("Echelon Connect Sport Bike") { this->addDeviceName("ECH", comparison::StartsWith); diff --git a/tst/Devices/FTMSBike/ftmsbiketestdata.cpp b/tst/Devices/FTMSBike/ftmsbiketestdata.cpp index 1fcfa5619..bbb8c9469 100644 --- a/tst/Devices/FTMSBike/ftmsbiketestdata.cpp +++ b/tst/Devices/FTMSBike/ftmsbiketestdata.cpp @@ -1,5 +1,9 @@ #include "ftmsbiketestdata.h" +#include "Devices/SnodeBike/snodebiketestdata.h" +#include "Devices/FitPlusBike/fitplusbiketestdata.h" +#include "Devices/StagesBike/stagesbiketestdata.h" + void FTMSBikeTestData::configureExclusions() { this->exclude(new SnodeBike1TestData()); this->exclude(new SnodeBike2TestData()); diff --git a/tst/Devices/FTMSBike/ftmsbiketestdata.h b/tst/Devices/FTMSBike/ftmsbiketestdata.h index 2c23b4244..4ab988841 100644 --- a/tst/Devices/FTMSBike/ftmsbiketestdata.h +++ b/tst/Devices/FTMSBike/ftmsbiketestdata.h @@ -7,12 +7,12 @@ #include "devices/ftmsbike/ftmsbike.h" -#include "Devices/SnodeBike/snodebiketestdata.h" -#include "Devices/FitPlusBike/fitplusbiketestdata.h" -#include "Devices/StagesBike/stagesbiketestdata.h" class FTMSBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new ftmsbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } void configureExclusions() override; FTMSBikeTestData(std::string testName) : BikeTestData(testName) { diff --git a/tst/Devices/FakeBike/fakebiketestdata.h b/tst/Devices/FakeBike/fakebiketestdata.h index 2679adb69..cb13a9ff3 100644 --- a/tst/Devices/FakeBike/fakebiketestdata.h +++ b/tst/Devices/FakeBike/fakebiketestdata.h @@ -9,6 +9,10 @@ class FakeBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new fakebike(options.noResistance, options.noHeartService, options.noVirtualDevice); + } + bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override { info.fake_bike = enable; return true; diff --git a/tst/Devices/FitPlusBike/fitplusbiketestdata.h b/tst/Devices/FitPlusBike/fitplusbiketestdata.h index 38668f036..266c25d46 100644 --- a/tst/Devices/FitPlusBike/fitplusbiketestdata.h +++ b/tst/Devices/FitPlusBike/fitplusbiketestdata.h @@ -9,6 +9,10 @@ class FitPlusBikeFSTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new fitplusbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } + bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override { info.fitplus_bike = enable; return true; @@ -27,7 +31,10 @@ class FitPlusBikeFSTestData : public BikeTestData { }; class FitPlusBikeMRKTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new fitplusbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: FitPlusBikeMRKTestData() : BikeTestData("FitPlus Bike (MRK, no settings)"){ diff --git a/tst/Devices/FlywheelBike/flywheelbiketestdata.h b/tst/Devices/FlywheelBike/flywheelbiketestdata.h index fd049195f..1660ae3d2 100644 --- a/tst/Devices/FlywheelBike/flywheelbiketestdata.h +++ b/tst/Devices/FlywheelBike/flywheelbiketestdata.h @@ -10,6 +10,9 @@ class FlywheelBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new flywheelbike(options.noResistance, options.noHeartService); + } FlywheelBikeTestData(std::string testName) : BikeTestData(testName) { } public: diff --git a/tst/Devices/HorizonGR7Bike/horizongr7biketestdata.h b/tst/Devices/HorizonGR7Bike/horizongr7biketestdata.h index 540ca42b6..f597feb04 100644 --- a/tst/Devices/HorizonGR7Bike/horizongr7biketestdata.h +++ b/tst/Devices/HorizonGR7Bike/horizongr7biketestdata.h @@ -7,7 +7,10 @@ class HorizonGR7BikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new horizongr7bike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: HorizonGR7BikeTestData() : BikeTestData("Horizon GR7 Bike") { this->addDeviceName("JFIC", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/InspireBike/inspirebiketestdata.h b/tst/Devices/InspireBike/inspirebiketestdata.h index b1156f430..cd0060553 100644 --- a/tst/Devices/InspireBike/inspirebiketestdata.h +++ b/tst/Devices/InspireBike/inspirebiketestdata.h @@ -6,7 +6,10 @@ class InspireBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new inspirebike(options.noResistance, options.noHeartService); + } public: InspireBikeTestData() : BikeTestData("Inspire Bike") { this->addDeviceName("IC", comparison::StartsWithIgnoreCase, 8); diff --git a/tst/Devices/KeepBike/keepbiketestdata.h b/tst/Devices/KeepBike/keepbiketestdata.h index 22229f184..bb7a77dab 100644 --- a/tst/Devices/KeepBike/keepbiketestdata.h +++ b/tst/Devices/KeepBike/keepbiketestdata.h @@ -8,7 +8,10 @@ class KeepBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new keepbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: KeepBikeTestData() : BikeTestData("Keep Bike") { this->addDeviceName("KEEP_BIKE_", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/M3IBike/m3ibiketestdata.h b/tst/Devices/M3IBike/m3ibiketestdata.h index 30d322b4e..f86431395 100644 --- a/tst/Devices/M3IBike/m3ibiketestdata.h +++ b/tst/Devices/M3IBike/m3ibiketestdata.h @@ -11,6 +11,9 @@ class M3IBikeTestData : public BikeTestData { protected: void configureBluetoothDeviceInfos(const QBluetoothDeviceInfo& info, bool enable, std::vector& bluetoothDeviceInfos) const override; + bike* doCreateInstance(const BikeOptions& options) override { + return new m3ibike(options.noResistance, options.noHeartService); + } public: M3IBikeTestData() : BikeTestData("M3I Bike") { this->addDeviceName("M3", comparison::StartsWith); diff --git a/tst/Devices/MCFBike/mcfbiketestdata.h b/tst/Devices/MCFBike/mcfbiketestdata.h index 6ad140307..bd26bf100 100644 --- a/tst/Devices/MCFBike/mcfbiketestdata.h +++ b/tst/Devices/MCFBike/mcfbiketestdata.h @@ -8,7 +8,10 @@ class MCFBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new mcfbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: MCFBikeTestData() : BikeTestData("MCF Bike") { this->addDeviceName("MCF-", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/MepanelBike/mepanelbiketestdata.h b/tst/Devices/MepanelBike/mepanelbiketestdata.h index 526773cc5..763633258 100644 --- a/tst/Devices/MepanelBike/mepanelbiketestdata.h +++ b/tst/Devices/MepanelBike/mepanelbiketestdata.h @@ -9,7 +9,10 @@ class MepanelBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new mepanelbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: MepanelBikeTestData() : BikeTestData("Mepanel Bike") { this->addDeviceName("MEPANEL", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/NPECableBike/npecablebiketestdata.h b/tst/Devices/NPECableBike/npecablebiketestdata.h index 00911091e..cf4168d4c 100644 --- a/tst/Devices/NPECableBike/npecablebiketestdata.h +++ b/tst/Devices/NPECableBike/npecablebiketestdata.h @@ -8,6 +8,9 @@ class NPECableBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new npecablebike(options.noResistance, options.noHeartService); + } NPECableBikeTestData(std::string testName) : BikeTestData(testName) {} public: deviceType get_expectedDeviceType() const override { return deviceType::NPECableBike; } diff --git a/tst/Devices/NautilusBike/nautilusbiketestdata.h b/tst/Devices/NautilusBike/nautilusbiketestdata.h index ca971c835..f5d376174 100644 --- a/tst/Devices/NautilusBike/nautilusbiketestdata.h +++ b/tst/Devices/NautilusBike/nautilusbiketestdata.h @@ -6,7 +6,10 @@ class NautilusBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new nautilusbike(options.noResistance, options.noHeartService, false, options.resistanceOffset, options.resistanceGain); + } public: NautilusBikeTestData(): BikeTestData("Nautilus Bike") { this->addDeviceName("NAUTILUS B", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/PafersBike/pafersbiketestdata.h b/tst/Devices/PafersBike/pafersbiketestdata.h index fac76b18d..7366dd3fd 100644 --- a/tst/Devices/PafersBike/pafersbiketestdata.h +++ b/tst/Devices/PafersBike/pafersbiketestdata.h @@ -7,6 +7,9 @@ class PafersBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new pafersbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override { // the treadmill is given priority info.pafers_treadmill = !enable; diff --git a/tst/Devices/ProFormBike/proformbiketestdata.h b/tst/Devices/ProFormBike/proformbiketestdata.h index db8f64eac..39c7186b3 100644 --- a/tst/Devices/ProFormBike/proformbiketestdata.h +++ b/tst/Devices/ProFormBike/proformbiketestdata.h @@ -7,7 +7,10 @@ class ProFormBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new proformbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: ProFormBikeTestData() : BikeTestData("ProForm Bike") { this->addDeviceName("I_EB", comparison::StartsWith); diff --git a/tst/Devices/ProFormWiFiBike/proformwifibiketestdata.h b/tst/Devices/ProFormWiFiBike/proformwifibiketestdata.h index 6211c167d..07be0fb76 100644 --- a/tst/Devices/ProFormWiFiBike/proformwifibiketestdata.h +++ b/tst/Devices/ProFormWiFiBike/proformwifibiketestdata.h @@ -8,6 +8,10 @@ class ProFormWiFiBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new proformwifibike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } + bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override { info.proformtdf4ip = enable ? this->get_testIP():QString(); return true; diff --git a/tst/Devices/RenphoBike/renphobiketestdata.cpp b/tst/Devices/RenphoBike/renphobiketestdata.cpp index d4960f3a1..be8f2f79d 100644 --- a/tst/Devices/RenphoBike/renphobiketestdata.cpp +++ b/tst/Devices/RenphoBike/renphobiketestdata.cpp @@ -1,4 +1,6 @@ #include "renphobiketestdata.h" +#include "Devices/FitPlusBike/fitplusbiketestdata.h" +#include "Devices/SnodeBike/snodebiketestdata.h" void RenphoBikeTestData::configureExclusions() { this->exclude(new FitPlusBikeFSTestData()); diff --git a/tst/Devices/RenphoBike/renphobiketestdata.h b/tst/Devices/RenphoBike/renphobiketestdata.h index 8bc2254ce..23b61d83f 100644 --- a/tst/Devices/RenphoBike/renphobiketestdata.h +++ b/tst/Devices/RenphoBike/renphobiketestdata.h @@ -1,13 +1,14 @@ #pragma once #include "Devices/Bike/biketestdata.h" -#include "Devices/FitPlusBike/fitplusbiketestdata.h" -#include "Devices/SnodeBike/snodebiketestdata.h" - #include "devices/renphobike/renphobike.h" class RenphoBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new renphobike(options.noResistance, options.noHeartService); + } + RenphoBikeTestData(std::string testName) : BikeTestData(testName) { } diff --git a/tst/Devices/Schwinn170Bike/schwinn170biketestdata.h b/tst/Devices/Schwinn170Bike/schwinn170biketestdata.h index 3d64746ec..4b30ea20d 100644 --- a/tst/Devices/Schwinn170Bike/schwinn170biketestdata.h +++ b/tst/Devices/Schwinn170Bike/schwinn170biketestdata.h @@ -5,7 +5,10 @@ class Schwinn170BikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new schwinn170bike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: Schwinn170BikeTestData() : BikeTestData("Schwinn 170 Bike") { diff --git a/tst/Devices/SchwinnIC4Bike/schwinnic4biketestdata.h b/tst/Devices/SchwinnIC4Bike/schwinnic4biketestdata.h index 9dce84056..678e5d348 100644 --- a/tst/Devices/SchwinnIC4Bike/schwinnic4biketestdata.h +++ b/tst/Devices/SchwinnIC4Bike/schwinnic4biketestdata.h @@ -6,7 +6,10 @@ class SchwinnIC4BikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new schwinnic4bike(options.noResistance, options.noHeartService); + } public: SchwinnIC4BikeTestData() : BikeTestData("Schwinn IC4 Bike") { diff --git a/tst/Devices/SkandikaWiryBike/skandikawirybiketestdata.h b/tst/Devices/SkandikaWiryBike/skandikawirybiketestdata.h index 41ee111ad..81ca608f4 100644 --- a/tst/Devices/SkandikaWiryBike/skandikawirybiketestdata.h +++ b/tst/Devices/SkandikaWiryBike/skandikawirybiketestdata.h @@ -7,7 +7,10 @@ class SkandikaWiryBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new skandikawiribike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: SkandikaWiryBikeTestData() : BikeTestData("Skandika Wiry Bike") { this->addDeviceName("BFCP", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/SnodeBike/snodebiketestdata.h b/tst/Devices/SnodeBike/snodebiketestdata.h index f504cf141..1b8a11959 100644 --- a/tst/Devices/SnodeBike/snodebiketestdata.h +++ b/tst/Devices/SnodeBike/snodebiketestdata.h @@ -6,6 +6,9 @@ class SnodeBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new snodebike(options.noResistance, options.noHeartService); + } SnodeBikeTestData(std::string testName) : BikeTestData(testName) { } void configureExclusions() override; diff --git a/tst/Devices/SoleBike/solebiketestdata.h b/tst/Devices/SoleBike/solebiketestdata.h index efca101f1..3cac78bc0 100644 --- a/tst/Devices/SoleBike/solebiketestdata.h +++ b/tst/Devices/SoleBike/solebiketestdata.h @@ -7,7 +7,10 @@ class SoleBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new solebike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: SoleBikeTestData() : BikeTestData("Sole Bike") { this->addDeviceName("LCB", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/SportsPlusBike/sportsplusbiketestdata.h b/tst/Devices/SportsPlusBike/sportsplusbiketestdata.h index 7e3746057..b1d55ebaa 100644 --- a/tst/Devices/SportsPlusBike/sportsplusbiketestdata.h +++ b/tst/Devices/SportsPlusBike/sportsplusbiketestdata.h @@ -7,7 +7,10 @@ class SportsPlusBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new sportsplusbike(options.noResistance, options.noHeartService); + } public: SportsPlusBikeTestData() : BikeTestData("Sports Plus Bike") { this->addDeviceName("CARDIOFIT", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/SportsTechBike/sportstechbiketestdata.h b/tst/Devices/SportsTechBike/sportstechbiketestdata.h index 7632a56eb..a3fd48824 100644 --- a/tst/Devices/SportsTechBike/sportstechbiketestdata.h +++ b/tst/Devices/SportsTechBike/sportstechbiketestdata.h @@ -7,7 +7,10 @@ class SportsTechBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new sportstechbike(options.noResistance, options.noHeartService); + } public: SportsTechBikeTestData() : BikeTestData("Sport Tech Bike") { this->addDeviceName("EW-BK", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/StagesBike/stagesbiketestdata.h b/tst/Devices/StagesBike/stagesbiketestdata.h index 0939c8add..3c4cb6022 100644 --- a/tst/Devices/StagesBike/stagesbiketestdata.h +++ b/tst/Devices/StagesBike/stagesbiketestdata.h @@ -5,6 +5,9 @@ class StagesBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new stagesbike(options.noResistance, options.noHeartService, options.noVirtualDevice); + } StagesBikeTestData(std::string testName): BikeTestData(testName) { } diff --git a/tst/Devices/TacxNeo2/tacxneo2testdata.h b/tst/Devices/TacxNeo2/tacxneo2testdata.h index 129327229..991cabdcc 100644 --- a/tst/Devices/TacxNeo2/tacxneo2testdata.h +++ b/tst/Devices/TacxNeo2/tacxneo2testdata.h @@ -7,7 +7,10 @@ class TacxNeo2TestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new tacxneo2(options.noResistance, options.noHeartService); + } public: TacxNeo2TestData() : BikeTestData("Tacx Neo 2 Bike") { this->addDeviceName("TACX NEO", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/TrxAppGateUSBBike/trxappgateusbbiketestdata.h b/tst/Devices/TrxAppGateUSBBike/trxappgateusbbiketestdata.h index aba3940de..0797e90f8 100644 --- a/tst/Devices/TrxAppGateUSBBike/trxappgateusbbiketestdata.h +++ b/tst/Devices/TrxAppGateUSBBike/trxappgateusbbiketestdata.h @@ -6,6 +6,9 @@ class TrxAppGateUSBBikeTestData : public BikeTestData { protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new trxappgateusbbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } TrxAppGateUSBBikeTestData(std::string testName) : BikeTestData(testName) { } diff --git a/tst/Devices/UltrasportBike/ultrasportbiketestdata.h b/tst/Devices/UltrasportBike/ultrasportbiketestdata.h index 762d849d8..c89b57c33 100644 --- a/tst/Devices/UltrasportBike/ultrasportbiketestdata.h +++ b/tst/Devices/UltrasportBike/ultrasportbiketestdata.h @@ -7,7 +7,10 @@ class UltrasportBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new ultrasportbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: UltrasportBikeTestData() : BikeTestData("Ultrasport Bike") { this->addDeviceName("X-BIKE", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/WahooKickrSnapBike/wahookickrsnapbiketestdata.h b/tst/Devices/WahooKickrSnapBike/wahookickrsnapbiketestdata.h index c22a8c437..78cd99133 100644 --- a/tst/Devices/WahooKickrSnapBike/wahookickrsnapbiketestdata.h +++ b/tst/Devices/WahooKickrSnapBike/wahookickrsnapbiketestdata.h @@ -7,7 +7,10 @@ class WahooKickrSnapBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new wahookickrsnapbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: WahooKickrSnapBikeTestData() : BikeTestData("Wahoo Kickr Snap Bike") { this->addDeviceName("KICKR SNAP", comparison::StartsWithIgnoreCase); diff --git a/tst/Devices/YesoulBike/yesoulbiketestdata.h b/tst/Devices/YesoulBike/yesoulbiketestdata.h index a63f35337..e903c3cb0 100644 --- a/tst/Devices/YesoulBike/yesoulbiketestdata.h +++ b/tst/Devices/YesoulBike/yesoulbiketestdata.h @@ -1,13 +1,13 @@ #pragma once - #include "Devices/Bike/biketestdata.h" - #include "devices/yesoulbike/yesoulbike.h" - class YesoulBikeTestData : public BikeTestData { - +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new yesoulbike(options.noResistance, options.noHeartService, options.resistanceOffset, options.resistanceGain); + } public: YesoulBikeTestData() : BikeTestData("Yesoul Bike") { this->addDeviceName(yesoulbike::bluetoothName, comparison::StartsWith); diff --git a/tst/Devices/biketestsuite.cpp b/tst/Devices/biketestsuite.cpp new file mode 100644 index 000000000..30c7b7ae9 --- /dev/null +++ b/tst/Devices/biketestsuite.cpp @@ -0,0 +1,230 @@ +#include "biketestsuite.h" +#include "Erg/bikeergfunctions.h" + +template +QList BikeTestSuite::getResistanceSamples() { + return this->getSamples(this->ergInterface->getResistanceLimits()); +} + +template +QList BikeTestSuite::getCadenceSamples() { + return this->getSamples(this->ergInterface->getCadenceLimits()); +} + +template +BikeTestSuite::BikeTestSuite() : testSettings("Roberto Viola", "QDomyos-Zwift Testing") {} + +template +void BikeTestSuite::SetUp() { + BikeOptions options; + + // activate the test settings before doing anything + this->testSettings.activate(); + + this->device =this->typeParam.createInstance(options); + this->ergInterface = new bikeergfunctions(this->device); +} + +template +void BikeTestSuite::TearDown() { + if(this->device) delete this->device; + if(this->ergInterface) delete this->ergInterface; + this->device = nullptr; + this->ergInterface = nullptr; +} + +template +void BikeTestSuite::test_powerFunctions_minResistance() { + const auto erg = this->ergInterface; + uint16_t p0, p1; + resistance_t r0, r1; + QStringList errors; + QString powerBeyondResistanceLimit = QStringLiteral("Power at C:%1 RPM not bounded at %6 resistance (R:%2, P:%3W), (R:%4, P:%5W)"); + + r0 = erg->getResistanceLimits().min(); + r1 = r0-1; + + // traverse the cadence edges checking the power is clipped to the values for the max and min resistance + for( uint32_t cadenceRPM : this->getCadenceSamples()) + { + p0 = erg->getPower(cadenceRPM, r0); + p1 = erg->getPower(cadenceRPM, r1); + + if(p0 != p1) + errors.append(powerBeyondResistanceLimit.arg(cadenceRPM).arg(r0).arg(p0).arg(r1).arg(p1).arg("minimum")); + } + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + + +template +void BikeTestSuite::test_powerFunctions_maxResistance() { + const auto erg = this->ergInterface; + uint16_t p0, p1; + resistance_t r0, r1; + QStringList errors; + QString powerBeyondResistanceLimit = QStringLiteral("Power at C:%1 RPM not bounded at %6 resistance (R:%2, P:%3W), (R:%4, P:%5W)"); + + r0 = erg->getResistanceLimits().max(); + r1 = r0+1; + + // traverse the cadence edges checking the power is clipped to the values for the max and min resistance + for(uint16_t cadenceRPM : this->getCadenceSamples()) + { + + p0 = erg->getPower(cadenceRPM, r0); + p1 = erg->getPower(cadenceRPM, r1); + + if(p0 != p1) + errors.append(powerBeyondResistanceLimit.arg(cadenceRPM).arg(r0).arg(p0).arg(r1).arg(p1).arg("maximum")); + } + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + +template +void BikeTestSuite::test_powerFunctions_minCadence() { + const auto erg = this->ergInterface; + uint16_t p0, p1; + QStringList errors; + + const int32_t c0 = erg->getCadenceLimits().min(), c1=c0-1; + + // traverse the resistance edge checking the power is clipped to the values for the max and min cadence + + QString powerBeyondCadenceLimit = QStringLiteral("Power at R:%1 not bounded at %6 cadence (C:%2 RPM, P:%3W), (C:%4 RPM, P:%5W)"); + + for( resistance_t r : this->getResistanceSamples()) + { + p0 = erg->getPower(c0, r); + p1 = erg->getPower(c1, r); + + if(p0!=p1) + errors.append(powerBeyondCadenceLimit.arg(r).arg(c0).arg(p0).arg(c1).arg(p1).arg("minimum")); + } + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + +template +void BikeTestSuite::test_powerFunctions_maxCadence() { + const auto erg = this->ergInterface; + uint16_t p0, p1; + QStringList errors; + + const int32_t c0 = erg->getCadenceLimits().max(), c1=c0+1; + + // traverse the resistance edge checking the power is clipped to the values for the max and min cadence + + QString powerBeyondCadenceLimit = QStringLiteral("Power at R:%1 not bounded at %6 cadence (C:%2 RPM, P:%3W), (C:%4 RPM, P:%5W)"); + + for( resistance_t r : this->getResistanceSamples()) + { + p0 = erg->getPower(c0, r); + p1 = erg->getPower(c1, r); + + if(p0!=p1) + errors.append(powerBeyondCadenceLimit.arg(r).arg(c0).arg(p0).arg(c1).arg(p1).arg("maximum")); + } + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + +template +void BikeTestSuite::test_powerFunctions_resistancePowerConversion() { + const auto erg = this->ergInterface; + QStringList errors; + + ASSERT_TRUE(this->testSettings.get_active()) << "TestSettings object should be active."; + this->testSettings.qsettings.setValue(QZSettings::watt_gain, 1.0); + this->testSettings.qsettings.setValue(QZSettings::watt_offset, 0.0); + + // test inverses + QString unexpectedResistance=QStringLiteral("P(C:%3, R:%1)=%2 but R(C:%3, P:%2)=%4 and P(C:%3, R:%4)=%5"); + //for(uint32_t cadenceRPM=minRPM; cadenceRPM<=maxRPM; cadenceRPM++) + for(uint16_t cadenceRPM : this->getCadenceSamples()) + { + uint16_t lastPower=0xFFFF; + for( resistance_t resistanceToPower : this->getResistanceSamples()) + //for(resistance_t resistanceToPower=minResistance; resistanceToPower<=maxResistance; resistanceToPower++) + { + uint16_t power = erg->getPower(cadenceRPM, resistanceToPower); + + // if this resistance reaches a new power level, check the inverse + if(power!=lastPower) + { + lastPower = power; + resistance_t resistanceFromPower = erg->getResistance(cadenceRPM, power); + + if(resistanceToPower!=resistanceFromPower) { + uint16_t newPower = erg->getPower(cadenceRPM, resistanceFromPower); + + errors.append(unexpectedResistance.arg(resistanceToPower).arg(power).arg(cadenceRPM).arg(resistanceFromPower).arg(newPower)); + } + + } + + } + } + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + +template +void BikeTestSuite::test_powerFunctions_resistancePelotonConversion() { + const auto erg = this->ergInterface; + QStringList errors; + + ASSERT_TRUE(this->testSettings.get_active()) << "TestSettings object should be active."; + this->testSettings.qsettings.setValue(QZSettings::watt_gain, 1.0); + this->testSettings.qsettings.setValue(QZSettings::watt_offset, 0.0); + + // test inverses + QString unexpectedResistance=QStringLiteral("R2P(R:%1)=%2 but P2R(P:%2)=%3 and R2P(R:%3)=%4"); + + int lastPeloton = 0xFFFFFFFF; + + for( resistance_t resistanceToPeloton : this->getResistanceSamples()) + //for(resistance_t resistanceToPower=minResistance; resistanceToPower<=maxResistance; resistanceToPower++) + { + int pelotonFromResistance = erg->toPeloton(resistanceToPeloton); + + // if this resistance reaches a new Peloton level, check the inverse + if(pelotonFromResistance!=lastPeloton) + { + lastPeloton = pelotonFromResistance; + resistance_t resistanceFromPeloton = erg->fromPeloton(pelotonFromResistance); + + if(resistanceToPeloton!=resistanceFromPeloton) { + // do it again for debugging + resistanceFromPeloton = erg->fromPeloton(pelotonFromResistance); + int newPeloton = erg->toPeloton(resistanceFromPeloton); + + errors.append(unexpectedResistance.arg(resistanceToPeloton).arg(pelotonFromResistance).arg(resistanceFromPeloton).arg(newPeloton)); + } + + } + + } + + + ASSERT_TRUE(errors.empty()) << errors.join('\n').toStdString(); +} + +template +template +QList BikeTestSuite::getSamples(minmax range) { + QList result; + T0 d = range.max()-range.min(); + T0 inc = d/10; + + if(inc<1) inc = 1; + + for(T0 v=range.min(); v<=range.max(); v+=inc) + result.append(v); + if(result.last()!=range.max()) + result.append(range.max()); + + return result; +} diff --git a/tst/Devices/biketestsuite.h b/tst/Devices/biketestsuite.h new file mode 100644 index 000000000..4db8ec5e9 --- /dev/null +++ b/tst/Devices/biketestsuite.h @@ -0,0 +1,112 @@ +#pragma once + +#include "gtest/gtest.h" +#include "devices.h" +#include "Erg/erginterface.h" + +#include "Tools/testsettings.h" + +template +class BikeTestSuite : public testing::Test { +private: + bike * device = nullptr; + +protected: + T typeParam; + + erginterface * ergInterface = nullptr; + + /** + * @brief Manages the QSettings used during the tests, separate from QSettings stored in the system generally. + */ + TestSettings testSettings; + + /** + * @brief Gets a subset of the range for testing samples. Increment varies depending on delta. + * @return A QList containing min, max and some, or sometimes all values in between. + */ + template + QList getSamples(minmax range); + + /** + * @brief Determines from provided or estimated minimum and maximum resistance, which values to test, to avoid testing all. + * @return + */ + virtual QList getResistanceSamples(); + + /** + * @brief Determines from provided or estimated minimum and maximum cadence, which values to test, to avoid testing all. + * @return + */ + virtual QList getCadenceSamples(); + +public: + BikeTestSuite(); + + // Sets up the test fixture. + void SetUp() override; + + // Tears down the test fixture. + virtual void TearDown() override; + + /** + * @brief Test that power doesn't change below the minimum cadence for a constant resistance. + */ + void test_powerFunctions_minCadence(); + + /** + * @brief Test that power doesn't change below the minimum resistance for a constant cadence. + */ + void test_powerFunctions_minResistance(); + + /** + * @brief Test that power doesn't change below the maximum resistance for a constant cadence. + */ + void test_powerFunctions_maxResistance(); + + /** + * @brief Test that power doesn't change above the maximum cadence for a constant resistance. + */ + void test_powerFunctions_maxCadence(); + + /** + * @brief Test that the resistance from power function returns the minimum resistance required to get the same power + * from the power-from-resistance function at the same cadence. + */ + void test_powerFunctions_resistancePowerConversion(); + + /** + * @brief Test that conversions to and from Peloton levels work. + */ + void test_powerFunctions_resistancePelotonConversion(); +}; + + +TYPED_TEST_SUITE(BikeTestSuite, BikeTestDataTypes); + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsMinCadence) { + + GTEST_SKIP() << "Disabled because no public way to set a negative cadence."; + + this->test_powerFunctions_minCadence(); +} + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsMaxCadence) { + this->test_powerFunctions_maxCadence(); +} + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsMinResistance) { + this->test_powerFunctions_minResistance(); +} + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsMaxResistance) { + this->test_powerFunctions_maxResistance(); +} + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsResistancePowerConversion) { + this->test_powerFunctions_resistancePowerConversion(); +} + +TYPED_TEST(BikeTestSuite, TestPowerFunctionsPelotonResistanceConversion) { + this->test_powerFunctions_resistancePelotonConversion(); +} diff --git a/tst/Devices/devices.h b/tst/Devices/devices.h index a63e73ad4..2836c38b1 100644 --- a/tst/Devices/devices.h +++ b/tst/Devices/devices.h @@ -1,11 +1,9 @@ -#ifndef DEVICES_H -#define DEVICES_H +#pragma once #include #include #include "gtest/gtest.h" -#include "bluetoothdevicetestdata.h" #include "ActivioTreadmill/activiotreadmilltestdata.h" #include "ApexBike/apexbiketestdata.h" #include "BkoolBike/bkoolbiketestdata.h" @@ -199,7 +197,58 @@ ZiproTreadmillTestData, iConceptBikeTestData, iConceptEllipticalTestData>; -#endif +using BikeTestDataTypes = ::testing::Types< +ApexBikeTestData, +BkoolBikeTestData, +CompuTrainerTestData, +CSCBike1TestData, +CSCBike2TestData, +ChronobikeTestData, +DomyosBikeTestData, +EchelonConnectSportBikeTestData, +FTMSBike1TestData, +FTMSBike2TestData, +FTMSBike3TestData, +FakeBikeTestData, +FitPlusBikeFSTestData, +FitPlusBikeMRKTestData, +FlywheelBike1TestData, +FlywheelBike2TestData, +HorizonGR7BikeTestData, +InspireBikeTestData, +KeepBikeTestData, +M3IBikeTestData, +MCFBikeTestData, +MepanelBikeTestData, +NPECableBike1TestData, +NPECableBike2TestData, +NautilusBikeTestData, +PafersBikeTestData, +ProFormBikeTestData, +ProFormWiFiBikeTestData, +RenphoBike1TestData, +RenphoBike2TestData, +Schwinn170BikeTestData, +SchwinnIC4BikeTestData, +SkandikaWiryBikeTestData, +SnodeBike1TestData, +SnodeBike2TestData, +SoleBikeTestData, +SportsPlusBikeTestData, +SportsTechBikeTestData, +StagesBike1TestData, +StagesBike2TestData, +TacxNeo2TestData, +TrxAppGateUSBBike1TestData, +TrxAppGateUSBBike2TestData, +UltrasportBikeTestData, +WahooKickrSnapBikeTestData, +YesoulBikeTestData, +iConceptBikeTestData>; + + + + diff --git a/tst/Devices/iConceptBike/iconceptbiketestdata.h b/tst/Devices/iConceptBike/iconceptbiketestdata.h index 164c5d56f..1dc2199ba 100644 --- a/tst/Devices/iConceptBike/iconceptbiketestdata.h +++ b/tst/Devices/iConceptBike/iconceptbiketestdata.h @@ -5,7 +5,12 @@ class iConceptBikeTestData : public BikeTestData { -void configureSettings(const DeviceDiscoveryInfo &info, bool enable, +protected: + bike* doCreateInstance(const BikeOptions& options) override { + return new iconceptbike(); + } + + void configureSettings(const DeviceDiscoveryInfo &info, bool enable, std::vector &configurations) const override { DeviceDiscoveryInfo config(info); diff --git a/tst/Erg/bikeergfunctions.cpp b/tst/Erg/bikeergfunctions.cpp new file mode 100644 index 000000000..c814dd503 --- /dev/null +++ b/tst/Erg/bikeergfunctions.cpp @@ -0,0 +1,28 @@ +#include "bikeergfunctions.h" + +void bikeergfunctions::setCadence(int32_t cadence) { this->device->cadenceSensor(cadence); } + +bikeergfunctions::bikeergfunctions(bike *device) : device(device) {} + +double bikeergfunctions::getPower(const int32_t cadence, resistance_t resistance) { + auto originalCadence = this->device->currentCadence().value(); + + this->setCadence(cadence); + auto result = this->device->wattsFromResistance(resistance); + this->setCadence(originalCadence); + return result; +} + +int32_t bikeergfunctions::getResistance(const int32_t cadence, const double power) { + auto originalCadence = this->device->currentCadence().value(); + this->setCadence(cadence); + auto result = this->device->resistanceFromPowerRequest(power); + this->setCadence(originalCadence); + return result; +} + +double bikeergfunctions::toPeloton(const resistance_t resistance) { return device->bikeResistanceToPeloton(resistance); } + +resistance_t bikeergfunctions::fromPeloton(const int pelotonResistance) { return device->pelotonToBikeResistance(pelotonResistance); } + + diff --git a/tst/Erg/bikeergfunctions.h b/tst/Erg/bikeergfunctions.h new file mode 100644 index 000000000..00fabb09b --- /dev/null +++ b/tst/Erg/bikeergfunctions.h @@ -0,0 +1,28 @@ +#pragma once + +#include "erginterface.h" +#include "bike.h" + +class bikeergfunctions : public virtual erginterface { + protected: + bike* device; + + void setCadence(int32_t cadence); +public: + bikeergfunctions(bike *device); + + + minmax getCadenceLimits() const override { return this->device->cadenceLimits(); } + + minmax getResistanceLimits() const override { return this->device->resistanceLimits(); } + + + double getPower(const int32_t cadence, const resistance_t resistance) override; + + + int32_t getResistance(const int32_t cadence, const double power) override; + + double toPeloton(const resistance_t resistance) override; + resistance_t fromPeloton(const int pelotonResistance) override; + +}; diff --git a/tst/Erg/erginterface.h b/tst/Erg/erginterface.h new file mode 100644 index 000000000..a06e60ae8 --- /dev/null +++ b/tst/Erg/erginterface.h @@ -0,0 +1,60 @@ +#pragma once + +#include "minmax.h" +#include "definitions.h" + +/** + * @brief An interface for power calculation functions + */ +class erginterface { + protected: + erginterface() {} + erginterface(const erginterface&) {} + public: + /** + * @brief The cadence domain of the power functions. + * @return + */ + virtual minmax getCadenceLimits() const = 0; + + /** + * @brief The inclusive bounds of resistance the device provides. + * @return + */ + virtual minmax getResistanceLimits() const = 0; + + /** + * @brief Gets the power in watts for the given cadence and resistance level. + * @param cadence The cadence in a unit appropriate for the device, e.g. revolutions/strides/strokes per minute. + * @param resistance The resistance level. + * @return + */ + virtual double getPower(const int32_t cadence, const resistance_t resistance) = 0; + + + /** + * @brief Gets the resistance required to acheive the specified power in watts at the specified cadence. + * @param cadence The cadence in a unit appropriate for the device, e.g. revolutions/strides/strokes per minute. + * @param power The power in watts to acheive. + * @return + */ + virtual int32_t getResistance(const int32_t cadence, const double power) = 0; + + /** + * @brief Converts the specified device resistance to its corresponding Peloton resistance level. + * @return + */ + virtual double toPeloton(const resistance_t resistance) = 0; + + /** + * @brief Converts the specified Peloton resistance level to its corresponding device resistance level. + * @return + */ + virtual resistance_t fromPeloton(const int32_t pelotonResistance) = 0; + + + /** + * @brief Destructor + */ + virtual ~erginterface() = default; +}; diff --git a/tst/main.cpp b/tst/main.cpp index 372fee8a4..a5e807336 100644 --- a/tst/main.cpp +++ b/tst/main.cpp @@ -1,8 +1,19 @@ - #include +#include +#include + +// https://forum.qt.io/topic/84229/is-there-a-canonical-way-to-set-up-qapplication-and-google-test-together/2 int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + QCoreApplication app{argc, argv}; + + QTimer::singleShot(0, [&]() + { + ::testing::InitGoogleTest(&argc, argv); + auto testResult = RUN_ALL_TESTS(); + app.exit(testResult); + }); + + return app.exec(); } diff --git a/tst/qdomyos-zwift-tests.pro b/tst/qdomyos-zwift-tests.pro index 861ac7d86..8cc125c67 100644 --- a/tst/qdomyos-zwift-tests.pro +++ b/tst/qdomyos-zwift-tests.pro @@ -5,7 +5,7 @@ include(gtest_dependency.pri) TEMPLATE = app -CONFIG += console c++11 +CONFIG += console c++17 CONFIG -= app_bundle CONFIG += thread CONFIG += androidextras @@ -19,10 +19,12 @@ SOURCES += \ Devices/SnodeBike/snodebiketestdata.cpp \ Devices/StagesBike/stagesbiketestdata.cpp \ Devices/TrxAppGateUSBTreadmill/trxappgateusbtreadmilltestdata.cpp \ + Devices/biketestsuite.cpp \ Devices/bluetoothdevicetestdata.cpp \ Devices/bluetoothdevicetestsuite.cpp \ Devices/bluetoothsignalreceiver.cpp \ Devices/devicediscoveryinfo.cpp \ + Erg/bikeergfunctions.cpp \ Erg/ergtabletestsuite.cpp \ ToolTests/testsettingstestsuite.cpp \ Tools/testsettings.cpp \ @@ -131,6 +133,7 @@ HEADERS += \ Devices/WahooKickrSnapBike/wahookickrsnapbiketestdata.h \ Devices/YesoulBike/yesoulbiketestdata.h \ Devices/ZiproTreadmill/ziprotreadmilltestdata.h \ + Devices/biketestsuite.h \ Devices/bluetoothdevicetestdata.h \ Devices/bluetoothdevicetestsuite.h \ Devices/bluetoothsignalreceiver.h \ @@ -140,6 +143,8 @@ HEADERS += \ Devices/iConceptElliptical/iconceptellipticaltestdata.h \ Devices/YpooElliptical/ypooellipticaltestdata.h \ Devices/TrxAppGateUsbElliptical/trxappgateusbellipticaltestdata.h \ + Erg/bikeergfunctions.h \ + Erg/erginterface.h \ Erg/ergtabletestsuite.h \ ToolTests/testsettingstestsuite.h \ Tools/testsettings.h