Auto Resistance from Zwift-QZ is not working on Proform Hybrid #1172

This commit is contained in:
Roberto Viola
2023-02-10 08:59:44 +01:00
parent 80f6a5a9ee
commit 3e8bbf57d2
2 changed files with 214 additions and 47 deletions

View File

@@ -342,10 +342,6 @@ double nordictrackelliptical::GetResistanceFromPacket(QByteArray packet) {
QSettings settings;
bool proform_hybrid_trainer_xt =
settings.value(QZSettings::proform_hybrid_trainer_xt, QZSettings::default_proform_hybrid_trainer_xt).toBool();
bool proform_hybrid_trainer_PFEL03815 =
settings
.value(QZSettings::proform_hybrid_trainer_PFEL03815, QZSettings::default_proform_hybrid_trainer_PFEL03815)
.toBool();
if (proform_hybrid_trainer_xt) {
switch (r) {
@@ -394,46 +390,6 @@ double nordictrackelliptical::GetResistanceFromPacket(QByteArray packet) {
case 0x27:
return 16;
}
} else if (proform_hybrid_trainer_PFEL03815) {
switch (r) {
case 0:
return 0;
case 2:
return 1;
case 4:
return 2;
case 7:
case 8:
return 3;
case 9:
return 4;
case 0xb:
case 0xc:
return 5;
case 0xe:
return 6;
case 0x10:
case 0x11:
return 7;
case 0x13:
return 8;
case 0x15:
return 9;
case 0x18:
return 10;
case 0x1a:
return 11;
case 0x1d:
return 12;
case 0x1f:
return 13;
case 0x22:
return 14;
case 0x24:
return 15;
case 0x27:
return 16;
}
} else {
switch (r) {
case 1:

View File

@@ -152,6 +152,10 @@ void proformbike::forceResistance(resistance_t requestResistance) {
bool proform_tdf_10 = settings.value(QZSettings::proform_tdf_10, QZSettings::default_proform_tdf_10).toBool();
bool nordictrack_gx_2_7 =
settings.value(QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7).toBool();
bool proform_hybrid_trainer_PFEL03815 =
settings
.value(QZSettings::proform_hybrid_trainer_PFEL03815, QZSettings::default_proform_hybrid_trainer_PFEL03815)
.toBool();
if (proform_studio || proform_tdf_10) {
const uint8_t res1[] = {0xfe, 0x02, 0x16, 0x03};
@@ -168,6 +172,90 @@ void proformbike::forceResistance(resistance_t requestResistance) {
writeCharacteristic((uint8_t *)res1, sizeof(res1), QStringLiteral("resistance1"), false, false);
writeCharacteristic((uint8_t *)res2, sizeof(res2), QStringLiteral("resistance2"), false, false);
writeCharacteristic((uint8_t *)res3, sizeof(res3), QStringLiteral("resistance3"), false, true);
} else if (proform_hybrid_trainer_PFEL03815) {
const uint8_t res1[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x32, 0x02, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res2[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xa3, 0x04, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res3[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x14, 0x07, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res4[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x85, 0x09, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res5[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xf6, 0x0b, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res6[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x67, 0x0e, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res7[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xd8, 0x10, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res8[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x49, 0x13, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res9[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xba, 0x15, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res10[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x2b, 0x18, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res11[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x9c, 0x1a, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res12[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x0d, 0x1d, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res13[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x7e, 0x1f, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res14[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xef, 0x21, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res15[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0x60, 0x24, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t res16[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xd1, 0x26, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00};
switch (requestResistance) {
case 1:
writeCharacteristic((uint8_t *)res1, sizeof(res1), QStringLiteral("resistance1"), false, true);
break;
case 2:
writeCharacteristic((uint8_t *)res2, sizeof(res2), QStringLiteral("resistance2"), false, true);
break;
case 3:
writeCharacteristic((uint8_t *)res3, sizeof(res3), QStringLiteral("resistance3"), false, true);
break;
case 4:
writeCharacteristic((uint8_t *)res4, sizeof(res4), QStringLiteral("resistance4"), false, true);
break;
case 5:
writeCharacteristic((uint8_t *)res5, sizeof(res5), QStringLiteral("resistance5"), false, true);
break;
case 6:
writeCharacteristic((uint8_t *)res6, sizeof(res6), QStringLiteral("resistance6"), false, true);
break;
case 7:
writeCharacteristic((uint8_t *)res7, sizeof(res7), QStringLiteral("resistance7"), false, true);
break;
case 8:
writeCharacteristic((uint8_t *)res8, sizeof(res8), QStringLiteral("resistance8"), false, true);
break;
case 9:
writeCharacteristic((uint8_t *)res9, sizeof(res9), QStringLiteral("resistance9"), false, true);
break;
case 10:
writeCharacteristic((uint8_t *)res10, sizeof(res10), QStringLiteral("resistance10"), false, true);
break;
case 11:
writeCharacteristic((uint8_t *)res11, sizeof(res11), QStringLiteral("resistance11"), false, true);
break;
case 12:
writeCharacteristic((uint8_t *)res12, sizeof(res12), QStringLiteral("resistance12"), false, true);
break;
case 13:
writeCharacteristic((uint8_t *)res13, sizeof(res13), QStringLiteral("resistance13"), false, true);
break;
case 14:
writeCharacteristic((uint8_t *)res14, sizeof(res14), QStringLiteral("resistance14"), false, true);
break;
case 15:
writeCharacteristic((uint8_t *)res15, sizeof(res15), QStringLiteral("resistance15"), false, true);
break;
case 16:
writeCharacteristic((uint8_t *)res16, sizeof(res16), QStringLiteral("resistance16"), false, true);
break;
}
} else if (nordictrack_gx_2_7) {
const uint8_t res1[] = {0xff, 0x0d, 0x02, 0x04, 0x02, 0x09, 0x07, 0x09, 0x02, 0x01,
0x04, 0xc2, 0x01, 0x00, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -415,6 +503,10 @@ void proformbike::update() {
bool proform_cycle_trainer_400 =
settings.value(QZSettings::proform_cycle_trainer_400, QZSettings::default_proform_cycle_trainer_400)
.toBool();
bool proform_hybrid_trainer_PFEL03815 =
settings
.value(QZSettings::proform_hybrid_trainer_PFEL03815, QZSettings::default_proform_hybrid_trainer_PFEL03815)
.toBool();
uint8_t noOpData1[] = {0xfe, 0x02, 0x19, 0x03};
uint8_t noOpData2[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x15, 0x07, 0x15, 0x02, 0x00,
@@ -463,9 +555,18 @@ void proformbike::update() {
uint8_t noOpData6_proform_cycle_trainer_400[] = {0xff, 0x05, 0x00, 0x00, 0x00, 0x81, 0xad, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// proform_hybrid_trainer_PFEL03815
uint8_t noOpData2_proform_hybrid_trainer_PFEL03815[] = {0x00, 0x12, 0x02, 0x04, 0x02, 0x13, 0x07, 0x13, 0x02, 0x00,
0x0d, 0x3c, 0x9e, 0x31, 0x00, 0x00, 0x40, 0x40, 0x00, 0x80};
uint8_t noOpData3_proform_hybrid_trainer_PFEL03815[] = {0xff, 0x05, 0x00, 0x00, 0x00, 0x85, 0xb9, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t noOpData4_proform_hybrid_trainer_PFEL03815[] = {0xfe, 0x02, 0x11, 0x02};
uint8_t noOpData5_proform_hybrid_trainer_PFEL03815[] = {0xff, 0x11, 0x02, 0x04, 0x02, 0x0d, 0x07, 0x0d, 0x02, 0x00,
0x07, 0xbc, 0x90, 0x70, 0x00, 0x00, 0x00, 0x40, 0x19, 0x00};
switch (counterPoll) {
case 0:
if (nordictrack_gx_2_7) {
if (nordictrack_gx_2_7 || proform_hybrid_trainer_PFEL03815) {
writeCharacteristic(noOpData4, sizeof(noOpData4), QStringLiteral("noOp"));
} else {
writeCharacteristic(noOpData1, sizeof(noOpData1), QStringLiteral("noOp"));
@@ -477,6 +578,9 @@ void proformbike::update() {
else if (nordictrack_gx_2_7) {
writeCharacteristic(noOpData2_nordictrack_gx_2_7, sizeof(noOpData2_nordictrack_gx_2_7),
QStringLiteral("noOp"));
} else if (proform_hybrid_trainer_PFEL03815) {
writeCharacteristic(noOpData2_proform_hybrid_trainer_PFEL03815, sizeof(noOpData2_proform_hybrid_trainer_PFEL03815),
QStringLiteral("noOp"));
} else if (proform_tour_de_france_clc)
writeCharacteristic(noOpData2_proform_tour_de_france_clc, sizeof(noOpData2_proform_tour_de_france_clc),
QStringLiteral("noOp"));
@@ -495,6 +599,9 @@ void proformbike::update() {
else if (nordictrack_gx_2_7) {
writeCharacteristic(noOpData3_nordictrack_gx_2_7, sizeof(noOpData3_nordictrack_gx_2_7),
QStringLiteral("noOp"));
} else if (proform_hybrid_trainer_PFEL03815) {
writeCharacteristic(noOpData3_proform_hybrid_trainer_PFEL03815, sizeof(noOpData3_proform_hybrid_trainer_PFEL03815),
QStringLiteral("noOp"));
} else if (proform_cycle_trainer_400)
writeCharacteristic(noOpData3_proform_cycle_trainer_400, sizeof(noOpData3_proform_cycle_trainer_400),
QStringLiteral("noOp"));
@@ -507,6 +614,9 @@ void proformbike::update() {
else if (nordictrack_gx_2_7) {
innerWriteResistance();
writeCharacteristic(noOpData7, sizeof(noOpData7), QStringLiteral("noOp"));
} else if (proform_hybrid_trainer_PFEL03815) {
writeCharacteristic(noOpData4_proform_hybrid_trainer_PFEL03815, sizeof(noOpData4_proform_hybrid_trainer_PFEL03815),
QStringLiteral("noOp"));
} else
writeCharacteristic(noOpData4, sizeof(noOpData4), QStringLiteral("noOp"));
break;
@@ -516,6 +626,10 @@ void proformbike::update() {
else if (nordictrack_gx_2_7) {
writeCharacteristic(noOpData5_nordictrack_gx_2_7, sizeof(noOpData5_nordictrack_gx_2_7),
QStringLiteral("noOp"));
} else if (proform_hybrid_trainer_PFEL03815) {
writeCharacteristic(noOpData5_proform_hybrid_trainer_PFEL03815, sizeof(noOpData5_proform_hybrid_trainer_PFEL03815),
QStringLiteral("noOp"));
innerWriteResistance();
} else
writeCharacteristic(noOpData5, sizeof(noOpData5), QStringLiteral("noOp"));
break;
@@ -559,7 +673,7 @@ void proformbike::update() {
requestResistance == -1) {
// this bike sends the frame noOpData7 only when it needs to change the resistance
counterPoll = 0;
} else if (counterPoll == 5 && nordictrack_gx_2_7) {
} else if (counterPoll == 5 && (nordictrack_gx_2_7 || proform_hybrid_trainer_PFEL03815)) {
counterPoll = 0;
}
@@ -664,6 +778,10 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte
settings.value(QZSettings::proform_tdf_jonseed_watt, QZSettings::default_proform_tdf_jonseed_watt).toBool();
bool nordictrack_gx_2_7 =
settings.value(QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7).toBool();
bool proform_hybrid_trainer_PFEL03815 =
settings
.value(QZSettings::proform_hybrid_trainer_PFEL03815, QZSettings::default_proform_hybrid_trainer_PFEL03815)
.toBool();
emit debug(QStringLiteral(" << ") + newValue.toHex(' '));
@@ -729,7 +847,81 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte
if (m_watts > 3000) {
m_watts = 0;
} else {
if (!nordictrack_gx_2_7) {
if (proform_hybrid_trainer_PFEL03815) {
switch ((uint8_t)newValue.at(11)) {
case 0:
Resistance = 0;
m_pelotonResistance = 0;
break;
case 2:
Resistance = 1;
m_pelotonResistance = 10;
break;
case 4:
Resistance = 2;
m_pelotonResistance = 20;
break;
case 7:
case 8:
Resistance = 3;
m_pelotonResistance = 25;
break;
case 9:
Resistance = 4;
m_pelotonResistance = 30;
break;
case 0xb:
case 0xc:
Resistance = 5;
m_pelotonResistance = 35;
break;
case 0xe:
Resistance = 6;
m_pelotonResistance = 40;
break;
case 0x10:
case 0x11:
Resistance = 7;
m_pelotonResistance = 45;
break;
case 0x13:
Resistance = 8;
m_pelotonResistance = 50;
break;
case 0x15:
Resistance = 9;
m_pelotonResistance = 55;
break;
case 0x18:
Resistance = 10;
m_pelotonResistance = 60;
break;
case 0x1a:
Resistance = 11;
m_pelotonResistance = 65;
break;
case 0x1d:
Resistance = 12;
m_pelotonResistance = 70;
break;
case 0x1f:
Resistance = 13;
m_pelotonResistance = 80;
break;
case 0x22:
Resistance = 14;
m_pelotonResistance = 90;
break;
case 0x24:
Resistance = 15;
m_pelotonResistance = 95;
break;
case 0x27:
Resistance = 16;
m_pelotonResistance = 100;
break;
}
} else if (!nordictrack_gx_2_7) {
switch ((uint8_t)newValue.at(11)) {
case 0x02:
Resistance = 1;
@@ -981,6 +1173,10 @@ void proformbike::btinit() {
settings.value(QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7).toBool();
bool proform_cycle_trainer_400 =
settings.value(QZSettings::proform_cycle_trainer_400, QZSettings::default_proform_cycle_trainer_400).toBool();
bool proform_hybrid_trainer_PFEL03815 =
settings
.value(QZSettings::proform_hybrid_trainer_PFEL03815, QZSettings::default_proform_hybrid_trainer_PFEL03815)
.toBool();
if (settings.value(QZSettings::proform_studio, QZSettings::default_proform_studio).toBool()) {
@@ -1188,6 +1384,21 @@ void proformbike::btinit() {
uint8_t initData12[] = {0xff, 0x08, 0x4a, 0xb6, 0x20, 0x98, 0x02, 0x00, 0x00, 0x93,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
writeCharacteristic(initData10, sizeof(initData10), QStringLiteral("init"), false, false);
QThread::msleep(400);
writeCharacteristic(initData11, sizeof(initData11), QStringLiteral("init"), false, false);
QThread::msleep(400);
writeCharacteristic(initData12, sizeof(initData12), QStringLiteral("init"), false, false);
QThread::msleep(400);
} else if(proform_hybrid_trainer_PFEL03815) {
max_resistance = 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,
0x9c, 0x82, 0xbe, 0xac, 0xc8, 0xfe, 0x1a, 0x00, 0x24, 0x4a};
uint8_t initData12[] = {0xff, 0x08, 0x66, 0x84, 0xe0, 0x80, 0x02, 0x00, 0x00, 0x8d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
writeCharacteristic(initData10, sizeof(initData10), QStringLiteral("init"), false, false);
QThread::msleep(400);
writeCharacteristic(initData11, sizeof(initData11), QStringLiteral("init"), false, false);