mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
3 Commits
Mobi-Rower
...
wahoo_comm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f49ac87ff8 | ||
|
|
2aba7ddfe1 | ||
|
|
d02ca5a934 |
@@ -34,6 +34,17 @@ wahookickrsnapbike::wahookickrsnapbike(bool noWriteResistance, bool noHeartServi
|
||||
refresh->start(settings.value(QZSettings::poll_device_time, QZSettings::default_poll_device_time).toInt());
|
||||
wheelCircumference::GearTable g;
|
||||
g.printTable();
|
||||
|
||||
// Setup op timeout handler for serialized commands
|
||||
_opTimeout.setSingleShot(true);
|
||||
connect(&_opTimeout, &QTimer::timeout, this, [this]() {
|
||||
// Timeout waiting for ack; clear and try next pending to avoid stall
|
||||
if (_currentOp != WahooOp::None) {
|
||||
emit debug(QStringLiteral("Ack timeout; releasing op and continuing queue"));
|
||||
}
|
||||
_currentOp = WahooOp::None;
|
||||
processNextPending();
|
||||
});
|
||||
}
|
||||
|
||||
void wahookickrsnapbike::restoreDefaultWheelDiameter() {
|
||||
@@ -305,10 +316,8 @@ void wahookickrsnapbike::update() {
|
||||
if(KICKR_SNAP) {
|
||||
inclinationChanged(lastGrade, lastGrade);
|
||||
} else {
|
||||
QByteArray a = setWheelCircumference(wheelCircumference::gearsToWheelDiameter(gears()));
|
||||
uint8_t b[20];
|
||||
memcpy(b, a.constData(), a.length());
|
||||
writeCharacteristic(b, a.length(), "setWheelCircumference", false, false);
|
||||
// Queue wheel circumference change (higher priority)
|
||||
sendWheelCircumferenceNow(wheelCircumference::gearsToWheelDiameter(gears()));
|
||||
lastGrade = 999; // to force a change
|
||||
}
|
||||
}
|
||||
@@ -442,6 +451,26 @@ void wahookickrsnapbike::handleCharacteristicValueChanged(const QBluetoothUuid &
|
||||
|
||||
qDebug() << QStringLiteral(" << ") << newValue.toHex(' ') << uuid;
|
||||
|
||||
// Detect acks for serialized commands (format: 0x01 <cmdId> 0x01 0x00 ...)
|
||||
if (newValue.size() >= 3 && (uint8_t)newValue.at(0) == 0x01) {
|
||||
uint8_t cmd = (uint8_t)newValue.at(1);
|
||||
uint8_t status = (uint8_t)newValue.at(2);
|
||||
if ((cmd == _setSimGrade || cmd == _setWheelCircumference) && status == 0x01) {
|
||||
|
||||
if(cmd == _setWheelCircumference) {
|
||||
homeform::singleton()->setToastRequested("Gear accepted from the trainer");
|
||||
}
|
||||
|
||||
// Ack received for our tracked op; release and continue
|
||||
if ((_currentOp == WahooOp::SimGrade && cmd == _setSimGrade) ||
|
||||
(_currentOp == WahooOp::WheelCircumference && cmd == _setWheelCircumference)) {
|
||||
_opTimeout.stop();
|
||||
_currentOp = WahooOp::None;
|
||||
processNextPending();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid == QBluetoothUuid::CyclingPowerMeasurement) {
|
||||
lastPacket = newValue;
|
||||
|
||||
@@ -964,10 +993,7 @@ void wahookickrsnapbike::inclinationChanged(double grade, double percentage) {
|
||||
emit debug(QStringLiteral("writing inclination ") + QString::number(grade));
|
||||
double g = grade;
|
||||
g += gears();
|
||||
QByteArray a = setSimGrade(g);
|
||||
uint8_t b[20];
|
||||
memcpy(b, a.constData(), a.length());
|
||||
writeCharacteristic(b, a.length(), "setSimGrade", false, false);
|
||||
sendSimGradeNow(g);
|
||||
} else {
|
||||
if(lastCommandErgMode) {
|
||||
lastGrade = grade + 1; // to force a refresh
|
||||
@@ -987,14 +1013,59 @@ void wahookickrsnapbike::inclinationChanged(double grade, double percentage) {
|
||||
g += gears() * 0.5;
|
||||
qDebug() << "adding gear offset so " << g;
|
||||
}
|
||||
QByteArray a = setSimGrade(g);
|
||||
uint8_t b[20];
|
||||
memcpy(b, a.constData(), a.length());
|
||||
writeCharacteristic(b, a.length(), "setSimGrade", false, false);
|
||||
sendSimGradeNow(g);
|
||||
lastCommandErgMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Send or enqueue: SimGrade
|
||||
void wahookickrsnapbike::sendSimGradeNow(double grade) {
|
||||
// If an operation is in flight, store latest grade and return
|
||||
if (_currentOp != WahooOp::None) {
|
||||
_pendingSimGrade = true;
|
||||
_pendingSimGradeValue = grade;
|
||||
return;
|
||||
}
|
||||
QByteArray a = setSimGrade(grade);
|
||||
uint8_t b[20];
|
||||
memcpy(b, a.constData(), a.length());
|
||||
_currentOp = WahooOp::SimGrade;
|
||||
// Send without blocking; wait for explicit ack in handleCharacteristicValueChanged
|
||||
writeCharacteristic(b, a.length(), "setSimGrade", false, false);
|
||||
_opTimeout.start(1000);
|
||||
}
|
||||
|
||||
// Send or enqueue: Wheel Circumference
|
||||
void wahookickrsnapbike::sendWheelCircumferenceNow(double mm) {
|
||||
// If an operation is in flight, prefer to hold latest wheel circ (priority for next send)
|
||||
if (_currentOp != WahooOp::None) {
|
||||
_pendingWheelCirc = true;
|
||||
_pendingWheelCircValue = mm;
|
||||
return;
|
||||
}
|
||||
QByteArray a = setWheelCircumference(mm);
|
||||
uint8_t b[20];
|
||||
memcpy(b, a.constData(), a.length());
|
||||
_currentOp = WahooOp::WheelCircumference;
|
||||
writeCharacteristic(b, a.length(), "setWheelCircumference", false, false);
|
||||
_opTimeout.start(1000);
|
||||
}
|
||||
|
||||
// Process next pending item, wheel circumference has priority
|
||||
void wahookickrsnapbike::processNextPending() {
|
||||
if (_currentOp != WahooOp::None) return;
|
||||
if (_pendingWheelCirc) {
|
||||
_pendingWheelCirc = false;
|
||||
sendWheelCircumferenceNow(_pendingWheelCircValue);
|
||||
return;
|
||||
}
|
||||
if (_pendingSimGrade) {
|
||||
_pendingSimGrade = false;
|
||||
sendSimGradeNow(_pendingSimGradeValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool wahookickrsnapbike::inclinationAvailableByHardware() {
|
||||
return KICKR_BIKE;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,18 @@ class wahookickrsnapbike : public bike {
|
||||
|
||||
bool writeCharacteristic(uint8_t *data, uint8_t data_len, QString info, bool disable_log = false,
|
||||
bool wait_for_response = false);
|
||||
|
||||
// Serialized command handling for setSimGrade and setWheelCircumference
|
||||
enum class WahooOp { None, SimGrade, WheelCircumference };
|
||||
WahooOp _currentOp = WahooOp::None;
|
||||
bool _pendingSimGrade = false;
|
||||
double _pendingSimGradeValue = 0.0;
|
||||
bool _pendingWheelCirc = false;
|
||||
double _pendingWheelCircValue = 0.0;
|
||||
QTimer _opTimeout;
|
||||
void processNextPending();
|
||||
void sendSimGradeNow(double grade);
|
||||
void sendWheelCircumferenceNow(double mm);
|
||||
uint16_t wattsFromResistance(double resistance);
|
||||
metric ResistanceFromFTMSAccessory;
|
||||
void startDiscover();
|
||||
|
||||
Reference in New Issue
Block a user