mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
59 Commits
fixing_tra
...
build-1015
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0c5a41e48 | ||
|
|
498ad13c15 | ||
|
|
6183101e2f | ||
|
|
fbdd5bd177 | ||
|
|
e65a209543 | ||
|
|
458642abab | ||
|
|
045a0d0c7d | ||
|
|
93713ae19d | ||
|
|
c2c581b6d0 | ||
|
|
3711e94026 | ||
|
|
eccaa89d77 | ||
|
|
97a67340a6 | ||
|
|
e24b4d0a55 | ||
|
|
3f58080193 | ||
|
|
deed740ac9 | ||
|
|
d19db65cf6 | ||
|
|
c5942d1d93 | ||
|
|
13851564d0 | ||
|
|
df3620f83a | ||
|
|
614957819f | ||
|
|
69d8bab7c8 | ||
|
|
7686ca48d0 | ||
|
|
9685a00b8a | ||
|
|
c69714bfad | ||
|
|
9da3d28995 | ||
|
|
90c8c167bc | ||
|
|
9962776f02 | ||
|
|
ef9ce3cffd | ||
|
|
0a717865ef | ||
|
|
329cf8beaa | ||
|
|
a7777f4185 | ||
|
|
fd200f43f6 | ||
|
|
7e9024a36e | ||
|
|
26c261957e | ||
|
|
5d38be8a5c | ||
|
|
a5ef8dfc21 | ||
|
|
39599dc7ad | ||
|
|
d765f13a13 | ||
|
|
1173f8f8bc | ||
|
|
6959993a40 | ||
|
|
45ca7b3b5b | ||
|
|
a84bfac840 | ||
|
|
c6c83085af | ||
|
|
f1c2414ad6 | ||
|
|
942d213216 | ||
|
|
0ad2f62e6c | ||
|
|
37f45b8439 | ||
|
|
821cddb342 | ||
|
|
f378bc3fff | ||
|
|
6ea8c002ac | ||
|
|
a95ab376c5 | ||
|
|
7d30088c7b | ||
|
|
fb3777b7ff | ||
|
|
d28acf3e96 | ||
|
|
553e83a075 | ||
|
|
857839b80f | ||
|
|
6e28f8a797 | ||
|
|
ddafafaba6 | ||
|
|
a746373894 |
@@ -4233,7 +4233,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "ADB_HOST=1";
|
||||
@@ -4427,7 +4427,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -4657,7 +4657,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@@ -4753,7 +4753,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = YES;
|
||||
@@ -4845,7 +4845,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -4961,7 +4961,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1011;
|
||||
CURRENT_PROJECT_VERSION = 1015;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
|
||||
ENABLE_BITCODE = YES;
|
||||
|
||||
@@ -227,6 +227,10 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
let quantity = HKQuantity(unit: unit,
|
||||
doubleValue: totalEnergyBurned)
|
||||
|
||||
if workoutSession.startDate == nil {
|
||||
return
|
||||
}
|
||||
|
||||
let sample = HKCumulativeQuantitySeriesSample(type: quantityType,
|
||||
quantity: quantity,
|
||||
start: workoutSession.startDate!,
|
||||
|
||||
@@ -215,6 +215,7 @@ void apexbike::characteristicChanged(const QLowEnergyCharacteristic &characteris
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -484,7 +484,8 @@ void bkoolbike::characteristicChanged(const QLowEnergyCharacteristic &characteri
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)currentHeart().value());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,10 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc
|
||||
|
||||
QString nordictrack_2950_ip =
|
||||
settings.value(QZSettings::nordictrack_2950_ip, QZSettings::default_nordictrack_2950_ip).toString();
|
||||
bool fake_bike =
|
||||
settings.value(QZSettings::applewatch_fakedevice, QZSettings::default_applewatch_fakedevice).toBool();
|
||||
bool fake_treadmill =
|
||||
settings.value(QZSettings::fakedevice_treadmill, QZSettings::default_fakedevice_treadmill).toBool();
|
||||
|
||||
if (settings.value(QZSettings::peloton_bike_ocr, QZSettings::default_peloton_bike_ocr).toBool() && !pelotonBike) {
|
||||
pelotonBike = new pelotonbike(noWriteResistance, noHeartService);
|
||||
@@ -47,6 +51,28 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc
|
||||
}
|
||||
// this signal is not associated to anything in this moment, since the homeform is not loaded yet
|
||||
this->signalBluetoothDeviceConnected(pelotonBike);
|
||||
} else if (fake_bike) {
|
||||
fakeBike = new fakebike(noWriteResistance, noHeartService, false);
|
||||
emit deviceConnected(QBluetoothDeviceInfo());
|
||||
connect(fakeBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered);
|
||||
connect(fakeBike, &fakebike::debug, this, &bluetooth::debug);
|
||||
if (this->discoveryAgent && !this->discoveryAgent->isActive()) {
|
||||
emit searchingStop();
|
||||
}
|
||||
// this signal is not associated to anything in this moment, since the homeform is not loaded yet
|
||||
this->signalBluetoothDeviceConnected(fakeBike);
|
||||
return;
|
||||
} else if (fake_treadmill) {
|
||||
fakeTreadmill = new faketreadmill(noWriteResistance, noHeartService, false);
|
||||
emit deviceConnected(QBluetoothDeviceInfo());
|
||||
connect(fakeTreadmill, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered);
|
||||
connect(fakeTreadmill, &faketreadmill::debug, this, &bluetooth::debug);
|
||||
if (this->discoveryAgent && !this->discoveryAgent->isActive()) {
|
||||
emit searchingStop();
|
||||
}
|
||||
// this signal is not associated to anything in this moment, since the homeform is not loaded yet
|
||||
this->signalBluetoothDeviceConnected(fakeBike);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
@@ -210,7 +210,8 @@ void chronobike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -293,7 +293,8 @@ void computrainerbike::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -252,7 +252,8 @@ void concept2skierg::characteristicChanged(const QLowEnergyCharacteristic &chara
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -417,7 +417,8 @@ void csaferower::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -291,7 +291,8 @@ void cscbike::characteristicChanged(const QLowEnergyCharacteristic &characterist
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -429,7 +429,8 @@ void domyosbike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -624,7 +624,8 @@ void domyosrower::characteristicChanged(const QLowEnergyCharacteristic &characte
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstVirtual) {
|
||||
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -298,7 +298,8 @@ void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic &
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -285,7 +285,8 @@ void echelonrower::characteristicChanged(const QLowEnergyCharacteristic &charact
|
||||
bool virtual_device_rower =
|
||||
settings.value(QZSettings::virtual_device_rower, QZSettings::default_virtual_device_rower).toBool();
|
||||
if (ios_peloton_workaround && cadence && !virtual_device_rower && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -62,6 +62,14 @@ void fakebike::update() {
|
||||
speedLimit());
|
||||
}
|
||||
|
||||
double weight = settings.value(QZSettings::weight, QZSettings::default_weight).toFloat();
|
||||
if (watts())
|
||||
KCal +=
|
||||
((((0.048 * ((double)watts()) + 1.19) * weight * 3.5) / 200.0) /
|
||||
(60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo(
|
||||
QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in
|
||||
// kg * 3.5) / 200 ) / 60
|
||||
|
||||
if (Cadence.value() > 0) {
|
||||
CrankRevs++;
|
||||
LastCrankEventTime += (uint16_t)(1024.0 / (((double)(Cadence.value())) / 60.0));
|
||||
@@ -132,7 +140,8 @@ void fakebike::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -99,7 +99,8 @@ void fakeelliptical::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -102,7 +102,8 @@ void fakerower::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -109,7 +109,8 @@ void faketreadmill::update() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -712,7 +712,8 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -219,7 +219,8 @@ void flywheelbike::updateStats() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -872,7 +872,8 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -368,7 +368,8 @@ void ftmsrower::characteristicChanged(const QLowEnergyCharacteristic &characteri
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -394,7 +394,8 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -315,7 +315,8 @@ void iconceptbike::readSocket() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -203,7 +203,8 @@ void inspirebike::characteristicChanged(const QLowEnergyCharacteristic &characte
|
||||
bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool();
|
||||
bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -261,7 +261,8 @@ void keepbike::characteristicChanged(const QLowEnergyCharacteristic &characteris
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -142,7 +142,7 @@ void lifespantreadmill::changeInclinationRequested(double grade, double percenta
|
||||
|
||||
uint32_t lifespantreadmill::GetStepsFromPacket(const QByteArray& packet) {
|
||||
if (packet.length() < 4) return 0;
|
||||
return (((uint8_t)packet[2]) << 8) | ((uint8_t)packet[3]);
|
||||
return ((uint16_t)((uint8_t)packet[2]) << 8) | (uint16_t)((uint8_t)packet[3]);
|
||||
}
|
||||
|
||||
void lifespantreadmill::update() {
|
||||
|
||||
@@ -731,7 +731,8 @@ void m3ibike::processAdvertising(const QByteArray &data) {
|
||||
bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool();
|
||||
bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -259,7 +259,8 @@ void mcfbike::characteristicChanged(const QLowEnergyCharacteristic &characterist
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -263,7 +263,8 @@ void mepanelbike::characteristicChanged(const QLowEnergyCharacteristic &characte
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -462,7 +462,8 @@ void nordictrackifitadbbike::processPendingDatagrams() {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadencep && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -427,7 +427,8 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact
|
||||
bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool();
|
||||
bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -260,7 +260,8 @@ void pafersbike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1639,7 +1639,8 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -367,7 +367,8 @@ void proformtelnetbike::characteristicChanged(const char *buff, int len) {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -626,7 +626,8 @@ void proformwifibike::characteristicChanged(const QString &newValue) {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -290,7 +290,8 @@ void proformwifitreadmill::characteristicChanged(const QString &newValue) {
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -369,7 +369,8 @@ void renphobike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -263,7 +263,8 @@ void schwinn170bike::characteristicChanged(const QLowEnergyCharacteristic &chara
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -369,7 +369,8 @@ void schwinnic4bike::characteristicChanged(const QLowEnergyCharacteristic &chara
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -288,7 +288,8 @@ void smartrowrower::characteristicChanged(const QLowEnergyCharacteristic &charac
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -327,7 +327,8 @@ void snodebike::characteristicChanged(const QLowEnergyCharacteristic &characteri
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -301,7 +301,8 @@ void solebike::characteristicChanged(const QLowEnergyCharacteristic &characteris
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -410,7 +410,8 @@ void stagesbike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -483,7 +483,8 @@ void strydrunpowersensor::characteristicChanged(const QLowEnergyCharacteristic &
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -700,7 +700,8 @@ void tacxneo2::characteristicChanged(const QLowEnergyCharacteristic &characteris
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)currentHeart().value());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -312,7 +312,8 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cad && h && firstVirtualBike) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -237,7 +237,8 @@ void ultrasportbike::characteristicChanged(const QLowEnergyCharacteristic &chara
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -560,7 +560,8 @@ void wahookickrsnapbike::characteristicChanged(const QLowEnergyCharacteristic &c
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -188,7 +188,8 @@ void yesoulbike::characteristicChanged(const QLowEnergyCharacteristic &character
|
||||
bool ios_peloton_workaround =
|
||||
settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool();
|
||||
if (ios_peloton_workaround && cadence && h && firstStateChanged) {
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime());
|
||||
h->workoutTrackingUpdate(Speed.value(), Cadence.value(), (uint16_t)m_watt.value(), calories().value());
|
||||
h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -688,6 +688,9 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) {
|
||||
}
|
||||
});
|
||||
});
|
||||
#else
|
||||
h = new lockscreen();
|
||||
h->appleWatchAppInstalled();
|
||||
#endif
|
||||
|
||||
if (QSslSocket::supportsSsl()) {
|
||||
@@ -3744,7 +3747,12 @@ void homeform::Start_inner(bool send_event_to_device) {
|
||||
videoPlaybackHalfPlayer->pause();
|
||||
}
|
||||
} else {
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#ifndef IO_UNDER_QT
|
||||
if(h && !h->appleWatchAppInstalled())
|
||||
h->startWorkout(bluetoothManager->device()->deviceType());
|
||||
#endif
|
||||
#endif
|
||||
if (bluetoothManager->device() && send_event_to_device) {
|
||||
bluetoothManager->device()->start();
|
||||
}
|
||||
@@ -3838,6 +3846,13 @@ void homeform::Stop() {
|
||||
|
||||
m_startRequested = false;
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#ifndef IO_UNDER_QT
|
||||
if(h && !h->appleWatchAppInstalled())
|
||||
h->stopWorkout();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
qDebug() << QStringLiteral("Stop pressed - paused") << paused << QStringLiteral("stopped") << stopped;
|
||||
|
||||
if (stopped) {
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#include <QQuickItemGrabResult>
|
||||
#include <QTextToSpeech>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include "ios/lockscreen.h"
|
||||
#endif
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
||||
#include <QAndroidJniEnvironment>
|
||||
#include <QtAndroid>
|
||||
#endif
|
||||
@@ -786,6 +788,9 @@ class homeform : public QObject {
|
||||
bool floating_open = false;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
lockscreen *h = nullptr;
|
||||
#endif
|
||||
bool m_locationServices = true;
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
|
||||
@@ -17,8 +17,11 @@ class ViewController: UIViewController {
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
WorkoutTracking.shared.authorizeHealthKit()
|
||||
WorkoutTracking.shared.observerHeartRateSamples()
|
||||
if #available(iOS 17.0, *) {
|
||||
WorkoutTracking.authorizeHealthKit()
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
WatchKitConnection.shared.delegate = self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,86 @@
|
||||
//
|
||||
// WorkoutTracking.swift
|
||||
// ElecDemo
|
||||
// WatchWorkoutTracking.swift
|
||||
// ElecDemo WatchKit Extension
|
||||
//
|
||||
// Created by NhatHM on 8/12/19.
|
||||
// Copyright © 2019 GST.PID. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import HealthKit
|
||||
|
||||
protocol WorkoutTrackingProtocol {
|
||||
func authorizeHealthKit()
|
||||
func observerHeartRateSamples()
|
||||
let SwiftDebug = swiftDebug()
|
||||
|
||||
protocol WorkoutTrackingDelegate: class {
|
||||
func didReceiveHealthKitHeartRate(_ heartRate: Double)
|
||||
func didReceiveHealthKitStepCounts(_ stepCounts: Double)
|
||||
func didReceiveHealthKitStepCadence(_ stepCadence: Double)
|
||||
func didReceiveHealthKitDistanceCycling(_ distanceCycling: Double)
|
||||
func didReceiveHealthKitActiveEnergyBurned(_ activeEnergyBurned: Double)
|
||||
}
|
||||
|
||||
class WorkoutTracking {
|
||||
protocol WorkoutTrackingProtocol {
|
||||
static func authorizeHealthKit()
|
||||
func startWorkOut(deviceType: UInt16)
|
||||
func stopWorkOut()
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
@objc class WorkoutTracking: NSObject {
|
||||
static let shared = WorkoutTracking()
|
||||
public static var lastDateMetric = Date()
|
||||
public static var distance = Double()
|
||||
public static var kcal = Double()
|
||||
var sport: Int = 0
|
||||
let healthStore = HKHealthStore()
|
||||
var observerQuery: HKObserverQuery!
|
||||
let configuration = HKWorkoutConfiguration()
|
||||
var workoutBuilder: HKWorkoutBuilder!
|
||||
var workoutInProgress: Bool = false
|
||||
|
||||
init() {
|
||||
weak var delegate: WorkoutTrackingDelegate?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
extension WorkoutTracking {
|
||||
func setSport(_ sport: Int) {
|
||||
self.sport = sport
|
||||
}
|
||||
|
||||
private func configWorkout() {
|
||||
var activityType = HKWorkoutActivityType.cycling
|
||||
if self.sport == 1 {
|
||||
activityType = HKWorkoutActivityType.running
|
||||
} else if self.sport == 2 {
|
||||
activityType = HKWorkoutActivityType.cycling
|
||||
} else if self.sport == 3 {
|
||||
activityType = HKWorkoutActivityType.rowing
|
||||
} else if self.sport == 4 {
|
||||
activityType = HKWorkoutActivityType.elliptical
|
||||
}
|
||||
|
||||
configuration.activityType = activityType
|
||||
configuration.locationType = .indoor
|
||||
|
||||
do {
|
||||
workoutBuilder = try HKWorkoutBuilder(healthStore: healthStore, configuration: configuration, device: .local())
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
func authorizeHealthKit() {
|
||||
|
||||
@objc static func requestAuth() {
|
||||
authorizeHealthKit()
|
||||
}
|
||||
|
||||
@objc public static func authorizeHealthKit() {
|
||||
if HKHealthStore.isHealthDataAvailable() {
|
||||
let infoToRead = Set([
|
||||
HKSampleType.quantityType(forIdentifier: .stepCount)!,
|
||||
@@ -33,86 +90,304 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
HKSampleType.workoutType()
|
||||
])
|
||||
|
||||
let infoToShare = Set([
|
||||
HKSampleType.quantityType(forIdentifier: .stepCount)!,
|
||||
HKSampleType.quantityType(forIdentifier: .heartRate)!,
|
||||
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
|
||||
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||
HKSampleType.workoutType()
|
||||
])
|
||||
var infoToShare: Set<HKSampleType> = []
|
||||
|
||||
healthStore.requestAuthorization(toShare: infoToShare, read: infoToRead) { (success, error) in
|
||||
if success {
|
||||
print("Authorization healthkit success")
|
||||
} else if let error = error {
|
||||
print(error)
|
||||
if #available(watchOSApplicationExtension 10.0, *) {
|
||||
infoToShare = Set([
|
||||
HKSampleType.quantityType(forIdentifier: .stepCount)!,
|
||||
HKSampleType.quantityType(forIdentifier: .heartRate)!,
|
||||
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
|
||||
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
|
||||
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||
HKSampleType.quantityType(forIdentifier: .cyclingPower)!,
|
||||
HKSampleType.quantityType(forIdentifier: .cyclingSpeed)!,
|
||||
HKSampleType.quantityType(forIdentifier: .cyclingCadence)!,
|
||||
HKSampleType.quantityType(forIdentifier: .runningPower)!,
|
||||
HKSampleType.quantityType(forIdentifier: .runningSpeed)!,
|
||||
HKSampleType.quantityType(forIdentifier: .runningStrideLength)!,
|
||||
HKSampleType.quantityType(forIdentifier: .runningVerticalOscillation)!,
|
||||
HKSampleType.quantityType(forIdentifier: .walkingSpeed)!,
|
||||
HKSampleType.quantityType(forIdentifier: .walkingStepLength)!,
|
||||
HKSampleType.workoutType()
|
||||
])
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
infoToShare = Set([
|
||||
HKSampleType.quantityType(forIdentifier: .stepCount)!,
|
||||
HKSampleType.quantityType(forIdentifier: .heartRate)!,
|
||||
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
|
||||
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
|
||||
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||
HKSampleType.workoutType()
|
||||
])
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
HKHealthStore().requestAuthorization(toShare: infoToShare, read: infoToRead) { (success, error) in
|
||||
if success {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Authorization healthkit success")
|
||||
} else if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
print("HealthKit not available")
|
||||
SwiftDebug.qtDebug("WorkoutTracking: HealthKit not avaiable")
|
||||
}
|
||||
}
|
||||
|
||||
func observerHeartRateSamples() {
|
||||
guard let heartRateSampleType = HKObjectType.quantityType(forIdentifier: .heartRate) else {
|
||||
return
|
||||
@objc func startWorkOut(deviceType: UInt16) {
|
||||
if(workoutInProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let observerQuery = observerQuery {
|
||||
healthStore.stop(observerQuery)
|
||||
}
|
||||
|
||||
observerQuery = HKObserverQuery(sampleType: heartRateSampleType, predicate: nil) { [unowned self] (_, _, error) in
|
||||
WorkoutTracking.authorizeHealthKit()
|
||||
workoutInProgress = true;
|
||||
WorkoutTracking.lastDateMetric = Date()
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Start workout")
|
||||
setSport(Int(deviceType))
|
||||
configWorkout()
|
||||
workoutBuilder.beginCollection(withStart: Date()) { (success, error) in
|
||||
SwiftDebug.qtDebug(success.description)
|
||||
if let error = error {
|
||||
print("Error: \(error.localizedDescription)")
|
||||
return
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func stopWorkOut() {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Stop workout")
|
||||
|
||||
guard let quantityType = HKQuantityType.quantityType(
|
||||
forIdentifier: .activeEnergyBurned) else {
|
||||
return
|
||||
}
|
||||
|
||||
let unit = HKUnit.kilocalorie()
|
||||
let totalEnergyBurned = WorkoutTracking.kcal
|
||||
let quantity = HKQuantity(unit: unit,
|
||||
doubleValue: totalEnergyBurned)
|
||||
|
||||
let sample = HKCumulativeQuantitySeriesSample(type: quantityType,
|
||||
quantity: quantity,
|
||||
start: workoutBuilder.startDate!,
|
||||
end: Date())
|
||||
|
||||
workoutBuilder.add([sample]) {(success, error) in}
|
||||
|
||||
let unitDistance = HKUnit.mile()
|
||||
let miles = WorkoutTracking.distance
|
||||
let quantityMiles = HKQuantity(unit: unitDistance,
|
||||
doubleValue: miles)
|
||||
|
||||
if(sport == 2) {
|
||||
|
||||
guard let quantityTypeDistance = HKQuantityType.quantityType(
|
||||
forIdentifier: .distanceCycling) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.fetchLatestHeartRateSample { (sample) in
|
||||
guard let sample = sample else {
|
||||
|
||||
let sampleDistance = HKCumulativeQuantitySeriesSample(type: quantityTypeDistance,
|
||||
quantity: quantityMiles,
|
||||
start: workoutBuilder.startDate!,
|
||||
end: Date())
|
||||
|
||||
workoutBuilder.add([sampleDistance]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
self.workoutBuilder.endCollection(withEnd: Date()) { (success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
self.workoutBuilder.finishWorkout{ (workout, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
workout?.setValue(quantityMiles, forKey: "totalDistance")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
guard let quantityTypeDistance = HKQuantityType.quantityType(
|
||||
forIdentifier: .distanceWalkingRunning) else {
|
||||
return
|
||||
}
|
||||
|
||||
let sampleDistance = HKCumulativeQuantitySeriesSample(type: quantityTypeDistance,
|
||||
quantity: quantityMiles,
|
||||
start: workoutBuilder.startDate!,
|
||||
end: Date())
|
||||
|
||||
workoutBuilder.add([sampleDistance]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
self.workoutBuilder.endCollection(withEnd: Date()) { (success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
self.workoutBuilder.finishWorkout{ (workout, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
workout?.setValue(quantityMiles, forKey: "totalDistance")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
workoutInProgress = false;
|
||||
}
|
||||
|
||||
@objc func addMetrics(power: Double, cadence: Double, speed: Double, kcal: Double) {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: GET DATA: \(Date())")
|
||||
|
||||
if(workoutInProgress == false && power > 0) {
|
||||
startWorkOut(deviceType: 2) // FORCING BIKE!!!!!
|
||||
} else if(workoutInProgress == false && power == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Speed = speed / 100;
|
||||
|
||||
WorkoutTracking.kcal = kcal
|
||||
|
||||
if(sport == 2) {
|
||||
if #available(watchOSApplicationExtension 10.0, *) {
|
||||
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
|
||||
doubleValue: power)
|
||||
|
||||
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
|
||||
let heartRate = sample.quantity.doubleValue(for: heartRateUnit)
|
||||
print("Heart Rate Sample: \(heartRate)")
|
||||
//LocalNotificationHelper.fireHeartRate(heartRate)
|
||||
guard let powerType = HKQuantityType.quantityType(
|
||||
forIdentifier: .cyclingPower) else {
|
||||
return
|
||||
}
|
||||
let wattPerIntervalSample = HKQuantitySample(type: powerType,
|
||||
quantity: wattPerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
let cadencePerInterval = HKQuantity(unit: HKUnit.count().unitDivided(by: HKUnit.second()),
|
||||
doubleValue: cadence / 60.0)
|
||||
|
||||
guard let cadenceType = HKQuantityType.quantityType(
|
||||
forIdentifier: .cyclingCadence) else {
|
||||
return
|
||||
}
|
||||
let cadencePerIntervalSample = HKQuantitySample(type: cadenceType,
|
||||
quantity: cadencePerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([cadencePerIntervalSample]) {(success, error) in
|
||||
if success {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: OK")
|
||||
}
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
|
||||
doubleValue: (Speed / 3.6))
|
||||
|
||||
guard let speedType = HKQuantityType.quantityType(
|
||||
forIdentifier: .cyclingSpeed) else {
|
||||
return
|
||||
}
|
||||
let speedPerIntervalSample = HKQuantitySample(type: speedType,
|
||||
quantity: speedPerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
} else if(sport == 1) {
|
||||
if #available(watchOSApplicationExtension 10.0, *) {
|
||||
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
|
||||
doubleValue: power)
|
||||
|
||||
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
guard let powerType = HKQuantityType.quantityType(
|
||||
forIdentifier: .runningPower) else {
|
||||
return
|
||||
}
|
||||
let wattPerIntervalSample = HKQuantitySample(type: powerType,
|
||||
quantity: wattPerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
|
||||
doubleValue: Speed * 0.277778)
|
||||
|
||||
guard let speedType = HKQuantityType.quantityType(
|
||||
forIdentifier: .runningSpeed) else {
|
||||
return
|
||||
}
|
||||
let speedPerIntervalSample = HKQuantitySample(type: speedType,
|
||||
quantity: speedPerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}/* else if(sport == 2) {
|
||||
if #available(watchOSApplicationExtension 10.0, *) {
|
||||
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
|
||||
doubleValue: Speed * 0.277778)
|
||||
|
||||
guard let speedType = HKQuantityType.quantityType(
|
||||
forIdentifier: .walkingSpeed) else {
|
||||
return
|
||||
}
|
||||
let speedPerIntervalSample = HKQuantitySample(type: speedType,
|
||||
quantity: speedPerInterval,
|
||||
start: WorkoutTracking.lastDateMetric,
|
||||
end: Date())
|
||||
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}*/
|
||||
|
||||
healthStore.execute(observerQuery)
|
||||
healthStore.enableBackgroundDelivery(for: heartRateSampleType, frequency: .immediate) { (success, error) in
|
||||
print(success)
|
||||
if let error = error {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
// TODO HANDLE WALKING, ROWING AND ELLIPTICAL
|
||||
|
||||
WorkoutTracking.lastDateMetric = Date()
|
||||
}
|
||||
}
|
||||
|
||||
extension WorkoutTracking {
|
||||
private func fetchLatestHeartRateSample(completionHandler: @escaping (_ sample: HKQuantitySample?) -> Void) {
|
||||
guard let sampleType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) else {
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
let predicate = HKQuery.predicateForSamples(withStart: Date.distantPast, end: Date(), options: .strictEndDate)
|
||||
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
|
||||
let query = HKSampleQuery(sampleType: sampleType,
|
||||
predicate: predicate,
|
||||
limit: Int(HKObjectQueryNoLimit),
|
||||
sortDescriptors: [sortDescriptor]) { (_, results, error) in
|
||||
if let error = error {
|
||||
print("Error: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
|
||||
completionHandler(results?[0] as? HKQuantitySample)
|
||||
}
|
||||
|
||||
healthStore.execute(query)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
class lockscreen {
|
||||
public:
|
||||
bool appleWatchAppInstalled();
|
||||
void setTimerDisabled();
|
||||
void request();
|
||||
long heartRate();
|
||||
@@ -15,6 +16,10 @@ class lockscreen {
|
||||
void setSpeed(double speed);
|
||||
void setPower(double power);
|
||||
void setCadence(double cadence);
|
||||
void startWorkout(unsigned short deviceType);
|
||||
void stopWorkout();
|
||||
|
||||
void workoutTrackingUpdate(double speed, unsigned short cadence, unsigned short watt, unsigned short currentCalories);
|
||||
|
||||
// virtualbike
|
||||
void virtualbike_ios();
|
||||
@@ -28,7 +33,7 @@ class lockscreen {
|
||||
double virtualbike_getPowerRequested();
|
||||
bool virtualbike_updateFTMS(unsigned short normalizeSpeed, unsigned char currentResistance,
|
||||
unsigned short currentCadence, unsigned short currentWatt,
|
||||
unsigned short CrankRevolutions, unsigned short LastCrankEventTime, signed short Gears);
|
||||
unsigned short CrankRevolutions, unsigned short LastCrankEventTime, signed short Gears, unsigned short currentCalories);
|
||||
int virtualbike_getLastFTMSMessage(unsigned char *message);
|
||||
|
||||
// virtualrower
|
||||
@@ -38,7 +43,7 @@ class lockscreen {
|
||||
unsigned short currentCadence, unsigned short currentWatt,
|
||||
unsigned short CrankRevolutions, unsigned short LastCrankEventTime,
|
||||
unsigned short StrokesCount, unsigned int Distance, unsigned short KCal,
|
||||
unsigned short Pace);
|
||||
unsigned short Pace, unsigned short currentCalories);
|
||||
int virtualrower_getLastFTMSMessage(unsigned char *message);
|
||||
|
||||
// virtualtreadmill
|
||||
@@ -49,7 +54,7 @@ class lockscreen {
|
||||
double virtualtreadmill_getPowerRequested();
|
||||
bool virtualtreadmill_updateFTMS(unsigned short normalizeSpeed, unsigned char currentResistance,
|
||||
unsigned short currentCadence, unsigned short currentWatt,
|
||||
unsigned short currentInclination, unsigned long long currentDistance);
|
||||
unsigned short currentInclination, unsigned long long currentDistance, unsigned short currentCalories);
|
||||
|
||||
// volume
|
||||
double getVolume();
|
||||
|
||||
@@ -22,6 +22,7 @@ static virtualbike_ios_swift* _virtualbike = nil;
|
||||
static virtualbike_zwift* _virtualbike_zwift = nil;
|
||||
static virtualrower* _virtualrower = nil;
|
||||
static virtualtreadmill_zwift* _virtualtreadmill_zwift = nil;
|
||||
static WorkoutTracking* workoutTracking = nil;
|
||||
|
||||
static GarminConnect* Garmin = 0;
|
||||
|
||||
@@ -33,6 +34,36 @@ static zwift_protobuf_layer* zwiftProtobufLayer = nil;
|
||||
|
||||
static NSString* profile_selected;
|
||||
|
||||
bool lockscreen::appleWatchAppInstalled() {
|
||||
if ([WCSession isSupported]) {
|
||||
// Get the default session
|
||||
WCSession *session = [WCSession defaultSession];
|
||||
|
||||
// Activate the session
|
||||
[session activateSession];
|
||||
|
||||
// Check if a watch is paired and the app is installed
|
||||
if (session.isPaired && session.isWatchAppInstalled) {
|
||||
// An Apple Watch is paired and has the companion app installed
|
||||
qDebug() << "Apple Watch is paired and app is installed";
|
||||
return true;
|
||||
} else if (session.isPaired) {
|
||||
// An Apple Watch is paired but doesn't have the companion app
|
||||
qDebug() << "Apple Watch is paired but app is not installed";
|
||||
return false;
|
||||
} else {
|
||||
// No Apple Watch is paired
|
||||
qDebug() << "No Apple Watch is paired";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// This device doesn't support Watch connectivity
|
||||
qDebug() << "Watch connectivity is not supported on this device";
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void lockscreen::setTimerDisabled() {
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
|
||||
}
|
||||
@@ -45,7 +76,22 @@ void lockscreen::request()
|
||||
if (@available(iOS 13, *)) {
|
||||
Garmin = [[GarminConnect alloc] init];
|
||||
}
|
||||
_adb = [[AdbClient alloc] initWithVerbose:YES];
|
||||
// just to be sure, I built the library for iOS17 only but theorically we can use any iOS version
|
||||
if (@available(iOS 17, *)) {
|
||||
workoutTracking = [[WorkoutTracking alloc] init];
|
||||
[WorkoutTracking requestAuth];
|
||||
_adb = [[AdbClient alloc] initWithVerbose:YES];
|
||||
}
|
||||
}
|
||||
|
||||
void lockscreen::startWorkout(unsigned short deviceType) {
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking startWorkOutWithDeviceType:deviceType];
|
||||
}
|
||||
|
||||
void lockscreen::stopWorkout() {
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking stopWorkOut];
|
||||
}
|
||||
|
||||
long lockscreen::heartRate()
|
||||
@@ -106,6 +152,11 @@ void lockscreen::virtualbike_setCadence(unsigned short crankRevolutions, unsigne
|
||||
[_virtualbike updateCadenceWithCrankRevolutions:crankRevolutions LastCrankEventTime:lastCrankEventTime];
|
||||
}
|
||||
|
||||
void lockscreen::workoutTrackingUpdate(double speed, unsigned short cadence, unsigned short watt, unsigned short currentCalories) {
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking addMetricsWithPower:watt cadence:cadence*2 speed:speed * 100 kcal:currentCalories];
|
||||
}
|
||||
|
||||
void lockscreen::virtualbike_zwift_ios(bool disable_hr, bool garmin_bluetooth_compatibility, bool zwift_play_emulator, bool watt_bike_emulator)
|
||||
{
|
||||
_virtualbike_zwift = [[virtualbike_zwift alloc] initWithDisable_hr:disable_hr garmin_bluetooth_compatibility:garmin_bluetooth_compatibility zwift_play_emulator:zwift_play_emulator watt_bike_emulator:watt_bike_emulator];
|
||||
@@ -152,15 +203,21 @@ double lockscreen::virtualbike_getPowerRequested()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool lockscreen::virtualbike_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 CrankRevolutions, UInt16 LastCrankEventTime, signed short Gears)
|
||||
bool lockscreen::virtualbike_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 CrankRevolutions, UInt16 LastCrankEventTime, signed short Gears, UInt16 currentCalories)
|
||||
{
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking addMetricsWithPower:currentWatt cadence:currentCadence speed:normalizeSpeed kcal:currentCalories];
|
||||
|
||||
if(_virtualbike_zwift != nil)
|
||||
return [_virtualbike_zwift updateFTMSWithNormalizeSpeed:normalizeSpeed currentCadence:currentCadence currentResistance:currentResistance currentWatt:currentWatt CrankRevolutions:CrankRevolutions LastCrankEventTime:LastCrankEventTime Gears:Gears];
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool lockscreen::virtualrower_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 CrankRevolutions, UInt16 LastCrankEventTime, UInt16 StrokesCount, UInt32 Distance, UInt16 KCal, UInt16 Pace)
|
||||
bool lockscreen::virtualrower_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 CrankRevolutions, UInt16 LastCrankEventTime, UInt16 StrokesCount, UInt32 Distance, UInt16 KCal, UInt16 Pace, UInt16 currentCalories)
|
||||
{
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking addMetricsWithPower:currentWatt cadence:currentCadence speed:normalizeSpeed kcal:currentCalories];
|
||||
|
||||
if(_virtualrower != nil)
|
||||
return [_virtualrower updateFTMSWithNormalizeSpeed:normalizeSpeed currentCadence:currentCadence currentResistance:currentResistance currentWatt:currentWatt CrankRevolutions:CrankRevolutions LastCrankEventTime:LastCrankEventTime StrokesCount:StrokesCount Distance:Distance KCal:KCal Pace:Pace];
|
||||
return 0;
|
||||
@@ -212,8 +269,11 @@ double lockscreen::virtualtreadmill_getPowerRequested()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool lockscreen::virtualtreadmill_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 currentInclination, UInt64 currentDistance)
|
||||
bool lockscreen::virtualtreadmill_updateFTMS(UInt16 normalizeSpeed, UInt8 currentResistance, UInt16 currentCadence, UInt16 currentWatt, UInt16 currentInclination, UInt64 currentDistance, UInt16 currentCalories)
|
||||
{
|
||||
if(workoutTracking != nil && !appleWatchAppInstalled())
|
||||
[workoutTracking addMetricsWithPower:currentWatt cadence:currentCadence speed:normalizeSpeed kcal:currentCalories];
|
||||
|
||||
if(_virtualtreadmill_zwift != nil)
|
||||
return [_virtualtreadmill_zwift updateFTMSWithNormalizeSpeed:normalizeSpeed currentCadence:currentCadence currentResistance:currentResistance currentWatt:currentWatt currentInclination:currentInclination currentDistance:currentDistance];
|
||||
return 0;
|
||||
|
||||
@@ -1379,7 +1379,7 @@ void virtualbike::bikeProvider() {
|
||||
// really connected to a device
|
||||
if (h->virtualbike_updateFTMS(normalizeSpeed, (char)Bike->currentResistance().value(),
|
||||
(uint16_t)Bike->currentCadence().value() * 2, (uint16_t)normalizeWattage,
|
||||
Bike->currentCrankRevolutions(), Bike->lastCrankEventTime(), ((bike*)Bike)->gears())) {
|
||||
Bike->currentCrankRevolutions(), Bike->lastCrankEventTime(), ((bike*)Bike)->gears(), Bike->calories().value())) {
|
||||
h->virtualbike_setHeartRate(Bike->currentHeart().value());
|
||||
|
||||
uint8_t ftms_message[255];
|
||||
|
||||
@@ -347,7 +347,7 @@ void virtualrower::rowerProvider() {
|
||||
normalizeSpeed, (char)Rower->currentResistance().value(), (uint16_t)Rower->currentCadence().value() * 2,
|
||||
(uint16_t)normalizeWattage, Rower->currentCrankRevolutions(), Rower->lastCrankEventTime(),
|
||||
((rower *)Rower)->currentStrokesCount().value(), Rower->odometer() * 1000, Rower->calories().value(),
|
||||
QTime(0, 0, 0).secsTo(((rower *)Rower)->currentPace()))) {
|
||||
QTime(0, 0, 0).secsTo(((rower *)Rower)->currentPace()), Rower->calories().value())) {
|
||||
h->virtualrower_setHeartRate(Rower->currentHeart().value());
|
||||
|
||||
uint8_t ftms_message[255];
|
||||
|
||||
@@ -536,7 +536,7 @@ void virtualtreadmill::treadmillProvider() {
|
||||
if (h->virtualtreadmill_updateFTMS(
|
||||
normalizeSpeed, 0, (uint16_t)((treadmill *)treadMill)->currentCadence().value() * cadence_multiplier,
|
||||
(uint16_t)((treadmill *)treadMill)->wattsMetric().value(),
|
||||
treadMill->currentInclination().value() * 10, (uint64_t)(((treadmill *)treadMill)->odometer() * 1000.0))) {
|
||||
treadMill->currentInclination().value() * 10, (uint64_t)(((treadmill *)treadMill)->odometer() * 1000.0), ((treadmill *)treadMill)->calories().value())) {
|
||||
h->virtualtreadmill_setHeartRate(((treadmill *)treadMill)->currentHeart().value());
|
||||
lastSlopeChanged = h->virtualtreadmill_lastChangeCurrentSlope();
|
||||
if ((uint64_t)QDateTime::currentSecsSinceEpoch() < lastSlopeChanged + slopeTimeoutSecs)
|
||||
|
||||
Reference in New Issue
Block a user