-
-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathftmsbike.h
More file actions
242 lines (209 loc) · 8.09 KB
/
Copy pathftmsbike.h
File metadata and controls
242 lines (209 loc) · 8.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#ifndef FTMSBIKE_H
#define FTMSBIKE_H
#include <QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth/qlowenergyadvertisingdata.h>
#include <QtBluetooth/qlowenergyadvertisingparameters.h>
#include <QtBluetooth/qlowenergycharacteristic.h>
#include <QtBluetooth/qlowenergycharacteristicdata.h>
#include <QtBluetooth/qlowenergycontroller.h>
#include <QtBluetooth/qlowenergydescriptordata.h>
#include <QtBluetooth/qlowenergyservice.h>
#include <QtBluetooth/qlowenergyservicedata.h>
#include <QtCore/qbytearray.h>
#ifndef Q_OS_ANDROID
#include <QtCore/qcoreapplication.h>
#else
#include <QtGui/qguiapplication.h>
#endif
#include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtimer.h>
#include <QDateTime>
#include <QObject>
#include <QString>
#include "wheelcircumference.h"
#include "devices/bike.h"
#include "inclinationresistancetable.h"
#ifdef Q_OS_IOS
#include "ios/lockscreen.h"
#endif
enum FtmsControlPointCommand {
FTMS_REQUEST_CONTROL = 0x00,
FTMS_RESET,
FTMS_SET_TARGET_SPEED,
FTMS_SET_TARGET_INCLINATION,
FTMS_SET_TARGET_RESISTANCE_LEVEL,
FTMS_SET_TARGET_POWER,
FTMS_SET_TARGET_HEARTRATE,
FTMS_START_RESUME,
FTMS_STOP_PAUSE,
FTMS_SET_TARGETED_EXP_ENERGY,
FTMS_SET_TARGETED_STEPS,
FTMS_SET_TARGETED_STRIDES,
FTMS_SET_TARGETED_DISTANCE,
FTMS_SET_TARGETED_TIME,
FTMS_SET_TARGETED_TIME_TWO_HR_ZONES,
FTMS_SET_TARGETED_TIME_THREE_HR_ZONES,
FTMS_SET_TARGETED_TIME_FIVE_HR_ZONES,
FTMS_SET_INDOOR_BIKE_SIMULATION_PARAMS,
FTMS_SET_WHEEL_CIRCUMFERENCE,
FTMS_SPIN_DOWN_CONTROL,
FTMS_SET_TARGETED_CADENCE,
FTMS_RESPONSE_CODE = 0x80
};
enum FtmsResultCode {
FTMS_SUCCESS = 0x01,
FTMS_NOT_SUPPORTED,
FTMS_INVALID_PARAMETER,
FTMS_OPERATION_FAILED,
FTMS_CONTROL_NOT_PERMITTED
};
class ftmsbike : public bike {
Q_OBJECT
public:
ftmsbike(bool noWriteResistance, bool noHeartService, int8_t bikeResistanceOffset, double bikeResistanceGain);
~ftmsbike();
bool connected() override;
resistance_t pelotonToBikeResistance(int pelotonResistance) override;
resistance_t maxResistance() override { return max_resistance; }
resistance_t resistanceFromPowerRequest(uint16_t power) override;
void changePower(int32_t power) override;
double maxGears() override;
double minGears() override;
void enableManualResistancePowerAdjustment(resistance_t resistance);
// Most FTMS bikes can use QZ's software ERG emulation, but FS-YK devices
// should stay on direct resistance control because it doesn't send the current resistance value and it conflicts
// with the PID HR method
bool ergModeSupportedAvailableBySoftware() override { return !FS_YK; }
bool inclinationAvailableBySoftware() override { return !resistance_lvl_mode; }
private:
bool writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false,
bool wait_for_response = false);
void writeCharacteristicZwiftPlay(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false,
bool wait_for_response = false);
void zwiftPlayInit();
void startDiscover();
void setWheelDiameter(double diameter);
uint16_t watts() override;
void init();
void forceResistance(resistance_t requestResistance);
void forcePower(int16_t requestPower);
void forceInclination(double requestInclination);
void sendZwiftPlayInclination(double inclination);
uint16_t wattsFromResistance(double resistance);
QTimer *refresh;
// Gear modification constants
static constexpr int GEARS_SLOPE_MULTIPLIER = 50;
QList<QLowEnergyService *> gattCommunicationChannelService;
QLowEnergyCharacteristic gattWriteCharControlPointId;
QLowEnergyService *gattFTMSService = nullptr;
QLowEnergyCharacteristic zwiftPlayWriteChar;
QLowEnergyService *zwiftPlayService = nullptr;
uint8_t sec1Update = 0;
QByteArray lastPacket;
QByteArray lastPacketFromFTMS;
QDateTime lastRefreshCharacteristicChangedPower = QDateTime::currentDateTime();
QDateTime lastRefreshCharacteristicChanged2AD2 = QDateTime::currentDateTime();
QDateTime lastRefreshCharacteristicChanged2ACE = QDateTime::currentDateTime();
QDateTime lastDomyosResistanceCommand = QDateTime::currentDateTime().addSecs(-60);
QDateTime domyosResistanceRetryAfter = QDateTime::currentDateTime().addSecs(-60);
bool ftmsFrameReceived = false;
uint8_t firstStateChanged = 0;
int8_t bikeResistanceOffset = 4;
double bikeResistanceGain = 1.0;
double lastGearValue = -1;
int max_resistance = 100;
bool initDone = false;
bool initRequest = false;
bool noWriteResistance = false;
bool noHeartService = false;
bool powerForced = false;
resistance_t m_lastErgResistance = 0;
resistance_t m_pendingErgResistance = -1;
QDateTime m_pendingErgResistanceTime;
bool manualResistancePowerAdjustmentActive = false;
bool manualResistancePowerAdjustmentToastShown = false;
resistance_t manualResistanceTarget = 1;
bool resistance_lvl_mode = false;
bool resistance_received = false;
bool native_resistance_received = false;
QDateTime calculatedResistanceFallbackSince;
inclinationResistanceTable _inclinationResistanceTable;
// D500V2 workaround: track if we're awaiting start simulation command after request control
bool awaiting_start_simulation_after_request_control = false;
resistance_t lastDomyosRequestedResistance = -1;
bool DU30_bike = false;
bool ICSE = false;
bool DOMYOS = false;
bool D500V2 = false;
bool _3G_Cardio_RB = false;
bool SCH_190U = false;
bool SCH_290R = false;
bool D2RIDE = false;
bool WATTBIKE = false;
bool VFSPINBIKE = false;
bool SS2K = false;
bool DIRETO_XR = false;
bool JFBK5_0 = false;
bool BIKE_ = false;
bool SMB1 = false;
bool LYDSTO = false;
bool DMASUN = false;
bool SL010 = false;
bool REEBOK = false;
bool TITAN_7000 = false;
bool T2 = false;
bool FIT_BK = false;
bool YS_G1MPLUS = false;
bool EXPERT_SX9 = false;
bool PM5 = false;
bool THINK_X = false;
bool WLT8828 = false;
bool VANRYSEL_HT = false;
bool MAGNUS = false;
bool MRK_S26C = false;
bool MRK_S28 = false;
bool HAMMER = false;
bool YPBM = false;
bool SPORT01 = false;
bool FS_YK = false;
bool S18 = false;
bool ZIPRO_RAVE = false;
bool SPEEDRACEX = false;
bool USDC_D700 = false;
bool TOPUTURE_TEB5 = false;
bool SMARTBIKE_3DIGIT = false;
uint8_t secondsToResetTimer = 5;
int16_t T2_lastGear = 0;
uint8_t battery_level = 0;
bool wattReceived = false;
bool gearInclinationSent = false;
uint16_t oldLastCrankEventTime = 0;
uint16_t oldCrankRevs = 0;
QDateTime lastGoodCadence = QDateTime::currentDateTime();
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif
Q_SIGNALS:
void disconnected();
void debug(QString string);
public slots:
void deviceDiscovered(const QBluetoothDeviceInfo &device);
private slots:
void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue);
void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue);
void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue);
void characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue);
void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue);
void stateChanged(QLowEnergyService::ServiceState state);
void controllerStateChanged(QLowEnergyController::ControllerState state);
void serviceDiscovered(const QBluetoothUuid &gatt);
void serviceScanDone(void);
bool shouldUseCalculatedResistanceFallback(const QDateTime &now);
void update();
void error(QLowEnergyController::Error err);
void errorService(QLowEnergyService::ServiceError);
void ftmsCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue);
};
#endif // FTMSBIKE_H