diff --git a/src/ANT/ANT.cpp b/src/ANT/ANT.cpp index ccbe6d483..34a8082f2 100644 --- a/src/ANT/ANT.cpp +++ b/src/ANT/ANT.cpp @@ -72,6 +72,8 @@ const ant_sensor_type_t ANT::ant_sensor_types[] = { ANT_TACX_VORTEX_FREQUENCY, DEFAULT_NETWORK_NUMBER, "Tacx Vortex Smart", 'v', ":images/IconPower.png" }, { true, ANTChannel::CHANNEL_TYPE_FITNESS_EQUIPMENT, ANT_SPORT_FITNESS_EQUIPMENT_PERIOD, ANT_SPORT_FITNESS_EQUIPMENT_TYPE, ANT_FITNESS_EQUIPMENT_FREQUENCY, ANT_SPORT_NETWORK_NUMBER, "Fitness Equipment Control (FE-C)", 'f', ":images/IconPower.png" }, + { true, ANTChannel::CHANNEL_TYPE_TEMPE, ANT_SPORT_TEMPE_PERIOD, ANT_SPORT_TEMPE_TYPE, + ANT_SPORT_FREQUENCY, ANT_SPORT_NETWORK_NUMBER, "Tempe", 't', ":images/IconTemp.png" }, { false, ANTChannel::CHANNEL_TYPE_GUARD, 0, 0, 0, 0, "", '\0', "" } }; @@ -231,6 +233,11 @@ void ANT::setHb(double smo2, double thb) telemetry.setHb(smo2, thb); } +void ANT::setTemp(double temp) +{ + telemetry.setTemp(temp); +} + /*====================================================================== * Main thread functions; start, stop etc *====================================================================*/ diff --git a/src/ANT/ANT.h b/src/ANT/ANT.h index d1b590e3a..f7303d754 100644 --- a/src/ANT/ANT.h +++ b/src/ANT/ANT.h @@ -251,6 +251,7 @@ struct setChannelAtom { #define ANT_SPORT_FITNESS_EQUIPMENT_PERIOD 8192 #define ANT_FAST_QUARQ_PERIOD (8182/16) #define ANT_QUARQ_PERIOD (8182*4) +#define ANT_SPORT_TEMPE_PERIOD 8192 #define ANT_SPORT_HR_TYPE 0x78 #define ANT_SPORT_POWER_TYPE 11 @@ -265,6 +266,7 @@ struct setChannelAtom { #define ANT_FAST_QUARQ_TYPE_WAS 11 // before release 1.8 #define ANT_FAST_QUARQ_TYPE 0x60 #define ANT_QUARQ_TYPE 0x60 +#define ANT_SPORT_TEMPE_TYPE 0x19 #define ANT_SPORT_FREQUENCY 57 #define ANT_FOOTPOD_FREQUENCY 57 @@ -722,6 +724,8 @@ public: void setTrainerReady(bool status) { telemetry.setTrainerReady(status); } void setTrainerRunning(bool status) { telemetry.setTrainerRunning(status); } + void setTemp(double temp); + qint64 getElapsedTime(); private: diff --git a/src/ANT/ANTChannel.cpp b/src/ANT/ANTChannel.cpp index 6afcc6266..6f59aed6c 100644 --- a/src/ANT/ANTChannel.cpp +++ b/src/ANT/ANTChannel.cpp @@ -1242,6 +1242,13 @@ void ANTChannel::broadcastEvent(unsigned char *ant_message) } break; + case CHANNEL_TYPE_TEMPE: + { + if (antMessage.tempValid) + parent->setTemp(antMessage.temp/100.0); + } + break; + default: break; // unknown? } diff --git a/src/ANT/ANTChannel.h b/src/ANT/ANTChannel.h index f679a7495..4b3ed6da3 100644 --- a/src/ANT/ANTChannel.h +++ b/src/ANT/ANTChannel.h @@ -147,6 +147,7 @@ class ANTChannel : public QObject { CHANNEL_TYPE_CONTROL, CHANNEL_TYPE_TACX_VORTEX, CHANNEL_TYPE_FITNESS_EQUIPMENT, + CHANNEL_TYPE_TEMPE, CHANNEL_TYPE_GUARD }; typedef enum channeltype ChannelType; diff --git a/src/ANT/ANTMessage.cpp b/src/ANT/ANTMessage.cpp index ba7fd86b5..f38f8b399 100644 --- a/src/ANT/ANTMessage.cpp +++ b/src/ANT/ANTMessage.cpp @@ -809,6 +809,17 @@ ANTMessage::ANTMessage(ANT *parent, const unsigned char *message) { } break; + case ANTChannel::CHANNEL_TYPE_TEMPE: + { + if (data_page == 1){ + uint16_t val = message[10] | (message[11]<<8); + if (val != 0x8000) + tempValid = true; + temp = val; + } + } + break; + default: break; } @@ -934,6 +945,8 @@ void ANTMessage::init() fpodInstant = false; fpodSpeed=fpodCadence=0; fpodStrides=0; + tempValid = false; + temp=0; } ANTMessage ANTMessage::resetSystem() diff --git a/src/ANT/ANTMessage.h b/src/ANT/ANTMessage.h index 522abf3a1..fca14ef62 100644 --- a/src/ANT/ANTMessage.h +++ b/src/ANT/ANTMessage.h @@ -207,6 +207,10 @@ class ANTMessage { uint8_t fpodStrides; double fpodSpeed, fpodCadence; + // tempe + bool tempValid; + uint16_t temp; + private: void init(); }; diff --git a/src/Train/DialWindow.cpp b/src/Train/DialWindow.cpp index 783936814..cee7b3800 100644 --- a/src/Train/DialWindow.cpp +++ b/src/Train/DialWindow.cpp @@ -540,6 +540,10 @@ DialWindow::telemetryUpdate(const RealtimeData &rtData) valueLabel->setText(QString("%1").arg(value, 0, 'f', 2)); break; + case RealtimeData::Temp: + valueLabel->setText(QString("%1").arg(value, 0, 'f', 2)); + break; + default: valueLabel->setText(QString("%1").arg(round(displayValue))); break; diff --git a/src/Train/RealtimeData.cpp b/src/Train/RealtimeData.cpp index e8bd3a6ae..0bff71173 100644 --- a/src/Train/RealtimeData.cpp +++ b/src/Train/RealtimeData.cpp @@ -521,6 +521,9 @@ double RealtimeData::value(DataSeries series) const case FeO2: return feo2; break; + case Temp: return temp; + break; + case None: default: return 0; @@ -593,6 +596,7 @@ const QList &RealtimeData::listDataSeries() seriesList << Altitude; seriesList << RouteDistance; seriesList << DistanceRemaining; + seriesList << Temp; } return seriesList; } @@ -781,6 +785,9 @@ QString RealtimeData::seriesName(DataSeries series) case FeO2: return tr("Fraction O2 Expired"); break; + + case Temp: return tr("Temperature"); + break; } } @@ -868,3 +875,7 @@ double RealtimeData::getVCO2() const { return vco2; } double RealtimeData::getRER() const { return rer; } double RealtimeData::getTv() const { return tv; } double RealtimeData::getFeO2() const { return feo2; } + +void RealtimeData::setTemp(double temp) { this->temp = temp; } +double RealtimeData::getTemp() const { return temp; } + diff --git a/src/Train/RealtimeData.h b/src/Train/RealtimeData.h index fab4546f5..2c0a18fc3 100644 --- a/src/Train/RealtimeData.h +++ b/src/Train/RealtimeData.h @@ -54,7 +54,8 @@ public: DistanceRemaining, RightPowerPhaseBegin, RightPowerPhaseEnd, RightPowerPhasePeakBegin, RightPowerPhasePeakEnd, - Position, RightPCO, LeftPCO }; + Position, RightPCO, LeftPCO, + Temp }; typedef enum dataseries DataSeries; @@ -197,6 +198,9 @@ public: bool getTrainerConfigRequired() const; bool getTrainerBrakeFault() const; + void setTemp(double temp); + double getTemp() const; + uint8_t spinScan[24]; private: @@ -215,6 +219,7 @@ private: double latitude, longitude, altitude; double vo2, vco2, rf, rmv, tv, feo2; RealtimeData::riderPosition position; + double temp; std::chrono::high_resolution_clock::time_point wheelRpmSampleTime; diff --git a/src/Train/TrainSidebar.cpp b/src/Train/TrainSidebar.cpp index b5c30a0da..a004d964e 100644 --- a/src/Train/TrainSidebar.cpp +++ b/src/Train/TrainSidebar.cpp @@ -395,6 +395,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex mode = ErgFileFormat::erg; pendingConfigChange = false; + displayTemp = 0; displayWorkoutLap = 0; pwrcount = 0; cadcount = 0; @@ -1674,6 +1675,7 @@ void TrainSidebar::Stop(int deviceStatus) // when stop button is pressed hrcount = 0; spdcount = 0; lodcount = 0; + displayTemp = 0; displayWorkoutLap = 0; wbalr = 0; wbal = WPRIME; @@ -1724,6 +1726,7 @@ void TrainSidebar::updateData(RealtimeData &rtData) displayLpppb = rtData.getLpppb(); displayLpppe = rtData.getLpppe(); displayPosition = rtData.getPosition(); + displayTemp = rtData.getTemp(); // Gradient not supported return; } @@ -1913,6 +1916,7 @@ void TrainSidebar::guiUpdate() // refreshes the telemetry if (Devices[dev].type == DEV_ANTLOCAL || Devices[dev].type == DEV_NULL) { rtData.setHb(local.getSmO2(), local.gettHb()); //only moxy data from ant and robot devices right now + rtData.setTemp(local.getTemp()); } if (Devices[dev].type == DEV_NULL || Devices[dev].type == DEV_BT40) { @@ -2163,6 +2167,7 @@ void TrainSidebar::guiUpdate() // refreshes the telemetry displayLpppb = rtData.getLpppb(); displayLpppe = rtData.getLpppe(); displayPosition = rtData.getPosition(); + displayTemp = rtData.getTemp(); double weightKG = bicycle.MassKG(); double vs = computeInstantSpeed(weightKG, rtData.getSlope(), rtData.getAltitude(), rtData.getWatts()); @@ -2309,7 +2314,7 @@ void TrainSidebar::diskUpdate() recordFileStream << "," // headwind << "," << slopeStr - << "," // temp + << "," << displayTemp << "," << displayWorkoutLap << "," << displayLRBalance << "," << displayLTE diff --git a/src/Train/TrainSidebar.h b/src/Train/TrainSidebar.h index da82e2232..8ea9845d9 100644 --- a/src/Train/TrainSidebar.h +++ b/src/Train/TrainSidebar.h @@ -277,6 +277,7 @@ class TrainSidebar : public GcWindow double displayRppb, displayRppe, displayRpppb, displayRpppe; double displayLppb, displayLppe, displayLpppb, displayLpppe; RealtimeData::riderPosition displayPosition; // rider position (seated = 0, transistionToSeated = 1, standing = 2, transitionToStanding=3, aero = 10, off = 11) + double displayTemp; void maintainLapDistanceState();