mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
14 Commits
build-1226
...
zwift_api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2d8bd9dc3 | ||
|
|
f03068189b | ||
|
|
8e166ff6cf | ||
|
|
f1d2b5ec40 | ||
|
|
d858eff4cc | ||
|
|
ca4ce00743 | ||
|
|
534d39053e | ||
|
|
8fb3030933 | ||
|
|
f43db4fe31 | ||
|
|
98603ba8b8 | ||
|
|
ec85319987 | ||
|
|
5b9122e337 | ||
|
|
84e27e6db1 | ||
|
|
18543d5d71 |
@@ -182,6 +182,11 @@
|
||||
872DCC3B2A18D4C000EC9F68 /* moc_virtualdevice.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872DCC3A2A18D4C000EC9F68 /* moc_virtualdevice.cpp */; };
|
||||
873063BE259DF20000DA0F44 /* heartratebelt.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873063BC259DF20000DA0F44 /* heartratebelt.cpp */; };
|
||||
873063C0259DF2C500DA0F44 /* moc_heartratebelt.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873063BF259DF2C500DA0F44 /* moc_heartratebelt.cpp */; };
|
||||
8730A38B2B404081007E336D /* SwiftProtobuf in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38A2B404081007E336D /* SwiftProtobuf */; };
|
||||
8730A38D2B404081007E336D /* SwiftProtobufPluginLibrary in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */; };
|
||||
8730A38F2B404081007E336D /* protoc-gen-swift in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38E2B404081007E336D /* protoc-gen-swift */; };
|
||||
8730A3922B404159007E336D /* zwift_protobuf_layer.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8730A3912B404159007E336D /* zwift_protobuf_layer.swift */; };
|
||||
8730A3932B4078E6007E336D /* zwift_messages.pb.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8730A3902B4040AF007E336D /* zwift_messages.pb.swift */; };
|
||||
87310B1E266FBB59008BA0D6 /* smartrowrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B1B266FBB54008BA0D6 /* smartrowrower.cpp */; };
|
||||
87310B1F266FBB59008BA0D6 /* homefitnessbuddy.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B1C266FBB57008BA0D6 /* homefitnessbuddy.cpp */; };
|
||||
87310B22266FBB78008BA0D6 /* moc_homefitnessbuddy.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B20266FBB6E008BA0D6 /* moc_homefitnessbuddy.cpp */; };
|
||||
@@ -329,6 +334,8 @@
|
||||
878531652711A3E1004B153D /* activiotreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531612711A3E1004B153D /* activiotreadmill.cpp */; };
|
||||
878531682711A3EC004B153D /* moc_activiotreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531662711A3EB004B153D /* moc_activiotreadmill.cpp */; };
|
||||
878531692711A3EC004B153D /* moc_fakebike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531672711A3EB004B153D /* moc_fakebike.cpp */; };
|
||||
8785D5432B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */; };
|
||||
8785D5442B3DD105005A2EB7 /* moc_zwift_client_auth.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */; };
|
||||
878A331A25AB4FF800BD13E1 /* yesoulbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878A331725AB4FF800BD13E1 /* yesoulbike.cpp */; };
|
||||
878A331D25AB50C300BD13E1 /* moc_yesoulbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878A331B25AB50C200BD13E1 /* moc_yesoulbike.cpp */; };
|
||||
878C9E6928B77E7C00669129 /* nordictrackifitadbbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878C9E6828B77E7B00669129 /* nordictrackifitadbbike.cpp */; };
|
||||
@@ -909,6 +916,8 @@
|
||||
873063BC259DF20000DA0F44 /* heartratebelt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = heartratebelt.cpp; path = ../src/heartratebelt.cpp; sourceTree = "<group>"; };
|
||||
873063BD259DF20000DA0F44 /* heartratebelt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = heartratebelt.h; path = ../src/heartratebelt.h; sourceTree = "<group>"; };
|
||||
873063BF259DF2C500DA0F44 /* moc_heartratebelt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_heartratebelt.cpp; sourceTree = "<group>"; };
|
||||
8730A3902B4040AF007E336D /* zwift_messages.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = zwift_messages.pb.swift; path = "../src/zwift-api/zwift_messages.pb.swift"; sourceTree = "<group>"; };
|
||||
8730A3912B404159007E336D /* zwift_protobuf_layer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = zwift_protobuf_layer.swift; path = "../src/zwift-api/zwift_protobuf_layer.swift"; sourceTree = "<group>"; };
|
||||
87310B1A266FBB54008BA0D6 /* homefitnessbuddy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = homefitnessbuddy.h; path = ../src/homefitnessbuddy.h; sourceTree = "<group>"; };
|
||||
87310B1B266FBB54008BA0D6 /* smartrowrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = smartrowrower.cpp; path = ../src/smartrowrower.cpp; sourceTree = "<group>"; };
|
||||
87310B1C266FBB57008BA0D6 /* homefitnessbuddy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = homefitnessbuddy.cpp; path = ../src/homefitnessbuddy.cpp; sourceTree = "<group>"; };
|
||||
@@ -1133,6 +1142,10 @@
|
||||
878531632711A3E1004B153D /* fakebike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fakebike.h; path = ../src/fakebike.h; sourceTree = "<group>"; };
|
||||
878531662711A3EB004B153D /* moc_activiotreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_activiotreadmill.cpp; sourceTree = "<group>"; };
|
||||
878531672711A3EB004B153D /* moc_fakebike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_fakebike.cpp; sourceTree = "<group>"; };
|
||||
8785D53F2B3DD0EC005A2EB7 /* zwift_client_auth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zwift_client_auth.h; path = "../src/zwift-api/zwift_client_auth.h"; sourceTree = "<group>"; };
|
||||
8785D5402B3DD0EC005A2EB7 /* PlayerStateWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlayerStateWrapper.h; path = "../src/zwift-api/PlayerStateWrapper.h"; sourceTree = "<group>"; };
|
||||
8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_PlayerStateWrapper.cpp; sourceTree = "<group>"; };
|
||||
8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_zwift_client_auth.cpp; sourceTree = "<group>"; };
|
||||
8789DCDB6A4F681A76DF3F92 /* Qt5Widgets */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = Qt5Widgets; path = "/Users/cagnulein/Qt/5.15.2/ios/lib/libQt5Widgets$(QT_LIBRARY_SUFFIX).a"; sourceTree = "<absolute>"; };
|
||||
878A331725AB4FF800BD13E1 /* yesoulbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = yesoulbike.cpp; path = ../src/yesoulbike.cpp; sourceTree = "<group>"; };
|
||||
878A331825AB4FF800BD13E1 /* yesoulbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yesoulbike.h; path = ../src/yesoulbike.h; sourceTree = "<group>"; };
|
||||
@@ -1672,6 +1685,7 @@
|
||||
4FA524144B680D741D33EACB /* qtgraphicaleffectsprivate in Link Binary With Libraries */,
|
||||
879F74152893D732009A64C8 /* CoreMedia.framework in Link Binary With Libraries */,
|
||||
1C823E40F377B93A664EAC1B /* modelsplugin in Link Binary With Libraries */,
|
||||
8730A38D2B404081007E336D /* SwiftProtobufPluginLibrary in Link Binary With Libraries */,
|
||||
B9DED9CC16B0F3339F363FBF /* workerscriptplugin in Link Binary With Libraries */,
|
||||
023642106C14651D2E1F4D5D /* dialogplugin in Link Binary With Libraries */,
|
||||
133CA0345CD2BFB03079A655 /* qmlfolderlistmodelplugin in Link Binary With Libraries */,
|
||||
@@ -1680,6 +1694,7 @@
|
||||
3BD5A5F95DF5239184791B58 /* dialogsprivateplugin in Link Binary With Libraries */,
|
||||
EF98F8C34BE322582E9B73D7 /* qtquickcontrolsplugin in Link Binary With Libraries */,
|
||||
7C8D236C48F2964061C3457C /* widgetsplugin in Link Binary With Libraries */,
|
||||
8730A38B2B404081007E336D /* SwiftProtobuf in Link Binary With Libraries */,
|
||||
401B341C04019FFA2146E79D /* Qt5Widgets in Link Binary With Libraries */,
|
||||
61EC5BE7EEC8D905C63FF628 /* qmlplugin in Link Binary With Libraries */,
|
||||
877A080D2893DC4300C0F0AB /* CoreVideo.framework in Link Binary With Libraries */,
|
||||
@@ -1693,6 +1708,7 @@
|
||||
5A4A6C1B12D4D769431E876E /* qtquickcontrols2materialstyleplugin in Link Binary With Libraries */,
|
||||
A044AC393BA2327284BB63B4 /* qtquickcontrols2fusionstyleplugin in Link Binary With Libraries */,
|
||||
B413AFE7A08F2D63D57F683E /* qtquickcontrols2universalstyleplugin in Link Binary With Libraries */,
|
||||
8730A38F2B404081007E336D /* protoc-gen-swift in Link Binary With Libraries */,
|
||||
7BA3E396471B90F086588B5C /* qtgraphicaleffectsplugin in Link Binary With Libraries */,
|
||||
F020E5470020A5BF3EB828A3 /* qtquickcontrols2imaginestyleplugin in Link Binary With Libraries */,
|
||||
964DFEF4056724121ED9A98D /* Qt5QuickControls2 in Link Binary With Libraries */,
|
||||
@@ -1917,6 +1933,11 @@
|
||||
2EB56BE3C2D93CDAB0C52E67 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8730A3902B4040AF007E336D /* zwift_messages.pb.swift */,
|
||||
8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */,
|
||||
8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */,
|
||||
8785D5402B3DD0EC005A2EB7 /* PlayerStateWrapper.h */,
|
||||
8785D53F2B3DD0EC005A2EB7 /* zwift_client_auth.h */,
|
||||
8727C7D32B3BF1E4005429EB /* moc_proformtelnetbike.cpp */,
|
||||
8727C7D22B3BF1E4005429EB /* moc_QTelnet.cpp */,
|
||||
8727C7CC2B3BF1B8005429EB /* proformtelnetbike.cpp */,
|
||||
@@ -2289,6 +2310,7 @@
|
||||
C8CE72E7B224D8B886614E3F /* domyosbike.h */,
|
||||
8710707229C4A5E70094D0F3 /* GarminConnect.swift */,
|
||||
87A2E0202B2B024200E6168F /* swiftDebug.h */,
|
||||
8730A3912B404159007E336D /* zwift_protobuf_layer.swift */,
|
||||
);
|
||||
name = Sources;
|
||||
sourceTree = "<group>";
|
||||
@@ -2816,6 +2838,11 @@
|
||||
876E4E312594748100BD5714 /* PBXTargetDependency */,
|
||||
);
|
||||
name = qdomyoszwift;
|
||||
packageProductDependencies = (
|
||||
8730A38A2B404081007E336D /* SwiftProtobuf */,
|
||||
8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */,
|
||||
8730A38E2B404081007E336D /* protoc-gen-swift */,
|
||||
);
|
||||
productName = qdomyoszwift;
|
||||
productReference = 040B10E2EF2CEF79F2205FE2 /* qdomyoszwift.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
@@ -2891,6 +2918,9 @@
|
||||
Base,
|
||||
);
|
||||
mainGroup = E8C543AB96796ECAA2E65C57 /* qdomyoszwift */;
|
||||
packageReferences = (
|
||||
8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
);
|
||||
productRefGroup = FE0A091FDBFB3E9C31B7A1BD /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
@@ -3036,6 +3066,7 @@
|
||||
87C5F0D326285E7E0067A1B5 /* moc_mimecontentformatter.cpp in Compile Sources */,
|
||||
8718CBAB263063CE004BF4EE /* moc_templateinfosenderbuilder.cpp in Compile Sources */,
|
||||
C6B3CD471768392E18F85819 /* fit_accumulated_field.cpp in Compile Sources */,
|
||||
8730A3932B4078E6007E336D /* zwift_messages.pb.swift in Compile Sources */,
|
||||
3D7395B0A17915A06361C7F3 /* fit_accumulator.cpp in Compile Sources */,
|
||||
2A61806454201575EDB3F94F /* fit_buffer_encode.cpp in Compile Sources */,
|
||||
87F02E4229178545000DB52C /* moc_octaneelliptical.cpp in Compile Sources */,
|
||||
@@ -3071,6 +3102,7 @@
|
||||
87CC3B9D25A08812001EC5A8 /* moc_domyoselliptical.cpp in Compile Sources */,
|
||||
87900DC6268B672E000CB351 /* renphobike.cpp in Compile Sources */,
|
||||
879F16462847E55C00CE4945 /* proformellipticaltrainer.cpp in Compile Sources */,
|
||||
8730A3922B404159007E336D /* zwift_protobuf_layer.swift in Compile Sources */,
|
||||
87917A7728E768D200F8D9AC /* Client.swift in Compile Sources */,
|
||||
873824B927E64707004F1B46 /* moc_provider.cpp in Compile Sources */,
|
||||
8727A47727849EA600019B5D /* paferstreadmill.cpp in Compile Sources */,
|
||||
@@ -3136,6 +3168,7 @@
|
||||
87097D2F275EA9A30020EE6F /* sportsplusbike.cpp in Compile Sources */,
|
||||
333C629F93DB3941862924F7 /* fit_field_base.cpp in Compile Sources */,
|
||||
87473A9827ECAA0500C203F5 /* moc_proformrower.cpp in Compile Sources */,
|
||||
8785D5442B3DD105005A2EB7 /* moc_zwift_client_auth.cpp in Compile Sources */,
|
||||
EEC10275DF646075E08DDC9B /* fit_field_definition.cpp in Compile Sources */,
|
||||
87062645259480AB00D06586 /* LocalNotificationHelper.swift in Compile Sources */,
|
||||
8718CBA4263063BD004BF4EE /* templateinfosenderbuilder.cpp in Compile Sources */,
|
||||
@@ -3283,6 +3316,7 @@
|
||||
C3D1FD2587BF6F15B58BA675 /* moc_bluetooth.cpp in Compile Sources */,
|
||||
87062648259480B700D06586 /* WorkoutTracking.swift in Compile Sources */,
|
||||
8C3422A825EF7ECD78951307 /* moc_bluetoothdevice.cpp in Compile Sources */,
|
||||
8785D5432B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp in Compile Sources */,
|
||||
1FBBC7C86C436CAAAFD37E56 /* moc_domyostreadmill.cpp in Compile Sources */,
|
||||
876BFCA027BE35D8001D7645 /* moc_proformelliptical.cpp in Compile Sources */,
|
||||
873824BD27E64707004F1B46 /* moc_resolver_p.cpp in Compile Sources */,
|
||||
@@ -4508,6 +4542,35 @@
|
||||
defaultConfigurationName = Debug;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-protobuf.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 1.25.2;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
8730A38A2B404081007E336D /* SwiftProtobuf */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
productName = SwiftProtobuf;
|
||||
};
|
||||
8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
productName = SwiftProtobufPluginLibrary;
|
||||
};
|
||||
8730A38E2B404081007E336D /* protoc-gen-swift */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
productName = "protoc-gen-swift";
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 6DB9C3763D02B1415CD9D565 /* Project object */;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,13 @@ class lockscreen {
|
||||
// Elite Aria Fan
|
||||
void eliteAriaFan();
|
||||
void eliteAriaFan_fanSpeedRequest(unsigned char speed);
|
||||
|
||||
// Zwift API
|
||||
void zwift_api_decodemessage_player(const char* data, int len);
|
||||
float zwift_api_getaltitude();
|
||||
int zwift_api_getdistance();
|
||||
float zwift_api_getlatitude();
|
||||
float zwift_api_getlongitude();
|
||||
};
|
||||
|
||||
#endif // LOCKSCREEN_H
|
||||
|
||||
@@ -29,6 +29,8 @@ static AdbClient *_adb = 0;
|
||||
|
||||
static ios_eliteariafan* ios_eliteAriaFan = nil;
|
||||
|
||||
static zwift_protobuf_layer* zwiftProtobufLayer = nil;
|
||||
|
||||
void lockscreen::setTimerDisabled() {
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
|
||||
}
|
||||
@@ -37,6 +39,7 @@ void lockscreen::request()
|
||||
{
|
||||
h = [[healthkit alloc] init];
|
||||
[h request];
|
||||
zwiftProtobufLayer = [[zwift_protobuf_layer alloc] init];
|
||||
if (@available(iOS 13, *)) {
|
||||
Garmin = [[GarminConnect alloc] init];
|
||||
}
|
||||
@@ -298,4 +301,25 @@ void lockscreen::eliteAriaFan_fanSpeedRequest(unsigned char speed) {
|
||||
[ios_eliteAriaFan fanSpeedRequest:speed];
|
||||
}
|
||||
}
|
||||
|
||||
void lockscreen::zwift_api_decodemessage_player(const char* data, int len) {
|
||||
NSData *d = [NSData dataWithBytes:data length:len];
|
||||
[zwiftProtobufLayer getPlayerStateWithValue:d];
|
||||
}
|
||||
|
||||
float lockscreen::zwift_api_getaltitude() {
|
||||
return [zwiftProtobufLayer getAltitude];
|
||||
}
|
||||
|
||||
int lockscreen::zwift_api_getdistance() {
|
||||
return [zwiftProtobufLayer getDistance];
|
||||
}
|
||||
|
||||
float lockscreen::zwift_api_getlatitude() {
|
||||
return [zwiftProtobufLayer getLatitude];
|
||||
}
|
||||
|
||||
float lockscreen::zwift_api_getlongitude() {
|
||||
return [zwiftProtobufLayer getLongitude];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -282,7 +282,6 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
qputenv("QT_MULTIMEDIA_PREFERRED_PLUGINS", "windowsmediafoundation");
|
||||
#endif
|
||||
|
||||
@@ -291,6 +291,8 @@ HEADERS += \
|
||||
$$PWD/proformtelnetbike.h \
|
||||
$$PWD/windows_zwift_workout_paddleocr_thread.h \
|
||||
$$PWD/fakerower.h \
|
||||
$$PWD/zwift-api/PlayerStateWrapper.h \
|
||||
$$PWD/zwift-api/zwift_client_auth.h \
|
||||
virtualdevice.h \
|
||||
$$PWD/androidactivityresultreceiver.h \
|
||||
$$PWD/androidadblog.h \
|
||||
|
||||
@@ -690,8 +690,12 @@ const QString QZSettings::proformtdf1ip = QStringLiteral("proformtdf1ip");
|
||||
const QString QZSettings::default_proformtdf1ip = QStringLiteral("");
|
||||
const QString QZSettings::proform_bike_225_csx = QStringLiteral("proform_bike_225_csx");
|
||||
const QString QZSettings::proform_treadmill_l6_0s = QStringLiteral("proform_treadmill_l6_0s");
|
||||
const QString QZSettings::zwift_username = QStringLiteral("zwift_username");
|
||||
const QString QZSettings::default_zwift_username = QStringLiteral("username");
|
||||
const QString QZSettings::zwift_password = QStringLiteral("zwift_password");
|
||||
const QString QZSettings::default_zwift_password = QStringLiteral("password");
|
||||
|
||||
const uint32_t allSettingsCount = 579;
|
||||
const uint32_t allSettingsCount = 581;
|
||||
|
||||
QVariant allSettings[allSettingsCount][2] = {
|
||||
{QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles},
|
||||
@@ -1277,6 +1281,9 @@ QVariant allSettings[allSettingsCount][2] = {
|
||||
{QZSettings::proform_bike_225_csx, QZSettings::default_proform_bike_225_csx},
|
||||
{QZSettings::proform_treadmill_l6_0s, QZSettings::default_proform_treadmill_l6_0s},
|
||||
{QZSettings::proformtdf1ip, QZSettings::default_proformtdf1ip},
|
||||
{QZSettings::zwift_username, QZSettings::default_zwift_username},
|
||||
{QZSettings::zwift_password, QZSettings::default_zwift_password},
|
||||
|
||||
};
|
||||
|
||||
void QZSettings::qDebugAllSettings(bool showDefaults) {
|
||||
|
||||
@@ -1938,6 +1938,13 @@ class QZSettings {
|
||||
static const QString proformtdf1ip;
|
||||
static const QString default_proformtdf1ip;
|
||||
|
||||
static const QString zwift_username;
|
||||
static const QString default_zwift_username;
|
||||
|
||||
static const QString zwift_password;
|
||||
static const QString default_zwift_password;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write the QSettings values using the constants from this namespace.
|
||||
* @param showDefaults Optionally indicates if the default should be shown with the key.
|
||||
|
||||
@@ -859,6 +859,8 @@ import QtQuick.Dialogs 1.0
|
||||
// from version 2.16.30
|
||||
property bool proform_treadmill_l6_0s: false
|
||||
property string proformtdf1ip: ""
|
||||
property string zwift_username: ""
|
||||
property string zwift_password: ""
|
||||
}
|
||||
|
||||
function paddingZeros(text, limit) {
|
||||
@@ -4416,7 +4418,6 @@ import QtQuick.Dialogs 1.0
|
||||
}
|
||||
|
||||
AccordionElement {
|
||||
visible: OS_VERSION === "Other"
|
||||
title: qsTr("Zwift Options") + "\uD83E\uDD47"
|
||||
indicatRectColor: Material.color(Material.Grey)
|
||||
textColor: Material.color(Material.Grey)
|
||||
@@ -4424,6 +4425,84 @@ import QtQuick.Dialogs 1.0
|
||||
accordionContent: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
Label {
|
||||
text: qsTr("Username:")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
id: zwiftUsernameTextField
|
||||
text: settings.zwift_username
|
||||
horizontalAlignment: Text.AlignRight
|
||||
Layout.fillHeight: false
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onAccepted: settings.zwift_username = text
|
||||
onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length
|
||||
}
|
||||
Button {
|
||||
id: okZwiftUsernameButton
|
||||
text: "OK"
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: { settings.zwift_username = zwiftUsernameTextField.text; window.settings_restart_to_apply = true; toast.show("Setting saved!"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
text: qsTr("Enter the email address you use to login to Zwift. Ensure there are no spaces before or after your email. Click OK.")
|
||||
font.bold: true
|
||||
font.italic: true
|
||||
font.pixelSize: 9
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
color: Material.color(Material.Lime)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
Label {
|
||||
id: labelZwiftPassword
|
||||
//text: qsTr("Password:") + ((rootItem.zwiftLogin===-1)?"":(rootItem.zwiftLogin===1?"\u2705":"\u274c"))
|
||||
text: qsTr("Password:")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
id: zwiftPasswordTextField
|
||||
text: settings.zwift_password
|
||||
horizontalAlignment: Text.AlignRight
|
||||
Layout.fillHeight: false
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
inputMethodHints: Qt.ImhHiddenText
|
||||
echoMode: TextInput.PasswordEchoOnEdit
|
||||
onAccepted: settings.zwift_password = text
|
||||
onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length
|
||||
}
|
||||
Button {
|
||||
id: okZwiftPasswordButton
|
||||
text: "OK"
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: { settings.zwift_password = zwiftPasswordTextField.text; window.settings_restart_to_apply = true; toast.show("Setting saved!"); }
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
//text: qsTr("Enter the password you use to login to Zwift. Click OK. If you have entered the correct login credentials and the QZ is able to access your account, you will see a when you reopen QZ. This is a secure login, not accessible by anyone but you.")
|
||||
text: qsTr("Enter the password you use to login to Zwift. Click OK.")
|
||||
font.bold: true
|
||||
font.italic: true
|
||||
font.pixelSize: 9
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
color: Material.color(Material.Lime)
|
||||
}
|
||||
|
||||
SwitchDelegate {
|
||||
text: qsTr("Zwift Treadmill Auto Inclination")
|
||||
spacing: 0
|
||||
|
||||
@@ -29,6 +29,12 @@ trainprogram::trainprogram(const QList<trainrow> &rows, bluetooth *b, QString *d
|
||||
this->description = *description;
|
||||
if (tags)
|
||||
this->tags = *tags;
|
||||
|
||||
if(settings.value(QZSettings::zwift_username, QZSettings::default_zwift_username).toString().length() > 0) {
|
||||
zwift_auth_token = new AuthToken(settings.value(QZSettings::zwift_username, QZSettings::default_zwift_username).toString(), settings.value(QZSettings::zwift_password, QZSettings::default_zwift_password).toString());
|
||||
zwift_auth_token->getAccessToken();
|
||||
}
|
||||
|
||||
/*
|
||||
int c = 0;
|
||||
for (c = 0; c < rows.length(); c++) {
|
||||
@@ -572,7 +578,6 @@ void trainprogram::scheduler() {
|
||||
|
||||
QMutexLocker(&this->schedulerMutex);
|
||||
QSettings settings;
|
||||
|
||||
// outside the if case about a valid train program because the information for the floating window url should be
|
||||
// sent anyway
|
||||
if (settings.value(QZSettings::peloton_companion_workout_ocr, QZSettings::default_companion_peloton_workout_ocr)
|
||||
@@ -590,6 +595,54 @@ void trainprogram::scheduler() {
|
||||
(bluetoothManager->device()->currentSpeed().value() <= 0 &&
|
||||
!settings.value(QZSettings::continuous_moving, QZSettings::default_continuous_moving).toBool()) ||
|
||||
bluetoothManager->device()->isPaused()) {
|
||||
|
||||
if(bluetoothManager->device() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL &&
|
||||
settings.value(QZSettings::zwift_username, QZSettings::default_zwift_username).toString().length() > 0 &&
|
||||
zwift_auth_token->access_token.length() > 0) {
|
||||
if(!zwift_world) {
|
||||
zwift_world = new World(1, zwift_auth_token->getAccessToken());
|
||||
qDebug() << "creating zwift api world";
|
||||
}
|
||||
else {
|
||||
#ifdef Q_OS_IOS
|
||||
#ifndef IO_UNDER_QT
|
||||
if(!h)
|
||||
h = new lockscreen();
|
||||
if(zwift_player_id == -1) {
|
||||
QString id = zwift_world->player_id();
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document = QJsonDocument::fromJson(id.toLocal8Bit(), &parseError);
|
||||
QJsonObject ride = document.object();
|
||||
qDebug() << "zwift api player" << ride;
|
||||
zwift_player_id = ride[QStringLiteral("id")].toInt();
|
||||
} else {
|
||||
static int zwift_counter = 5;
|
||||
if(zwift_counter++ >= 4) {
|
||||
zwift_counter = 0;
|
||||
QByteArray b = zwift_world->playerStatus(zwift_player_id);
|
||||
h->zwift_api_decodemessage_player(b.data(), b.length());
|
||||
float alt = h->zwift_api_getaltitude();
|
||||
float distance = h->zwift_api_getdistance();
|
||||
static float old_distance = 0;
|
||||
static float old_alt = 0;
|
||||
|
||||
if(old_distance > 0) {
|
||||
float delta = distance - old_distance;
|
||||
float deltaA = alt - old_alt;
|
||||
float incline = (deltaA / delta) / 2.0;
|
||||
if(delta > 1) {
|
||||
qDebug() << "zwift api incline" << incline << delta << deltaA;
|
||||
bluetoothManager->device()->changeInclination(incline, incline);
|
||||
}
|
||||
}
|
||||
old_distance = distance;
|
||||
old_alt = alt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// in case no workout has been selected
|
||||
// Zwift OCR
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include "ios/lockscreen.h"
|
||||
#endif
|
||||
|
||||
#include "zwift-api/PlayerStateWrapper.h"
|
||||
#include "zwift-api/zwift_client_auth.h"
|
||||
|
||||
class trainrow {
|
||||
public:
|
||||
QTime duration = QTime(0, 0, 0, 0);
|
||||
@@ -155,6 +162,15 @@ private slots:
|
||||
|
||||
QUdpSocket* pelotonOCRsocket = nullptr;
|
||||
void pelotonOCRcomputeTime(QString t);
|
||||
|
||||
AuthToken* zwift_auth_token = nullptr;
|
||||
World* zwift_world = nullptr;
|
||||
int zwift_player_id = -1;
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
lockscreen *h = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // TRAINPROGRAM_H
|
||||
|
||||
178
src/zwift-api/PlayerStateWrapper.h
Normal file
178
src/zwift-api/PlayerStateWrapper.h
Normal file
@@ -0,0 +1,178 @@
|
||||
#ifndef PLAYERSTATEWRAPPER_H
|
||||
#define PLAYERSTATEWRAPPER_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QEventLoop>
|
||||
#include <QDebug>
|
||||
|
||||
class ZwiftRequest: public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZwiftRequest(const QString& getAccessToken) : getAccessToken(getAccessToken) {}
|
||||
|
||||
QString json(const QString& url) {
|
||||
QNetworkRequest request(QUrl(BASE_URL + url));
|
||||
request.setRawHeader("Accept", "application/json");
|
||||
request.setRawHeader("Authorization", "Bearer " + getAccessToken.toUtf8());
|
||||
|
||||
QNetworkReply* reply = manager.get(request);
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qDebug() << "Error: " << reply->errorString();
|
||||
return "";
|
||||
}
|
||||
|
||||
return reply->readAll();
|
||||
}
|
||||
|
||||
QByteArray protobuf(const QString& url) {
|
||||
QNetworkRequest request(QUrl(BASE_URL + url));
|
||||
request.setRawHeader("Accept", "application/x-protobuf-lite");
|
||||
request.setRawHeader("Authorization", "Bearer " + getAccessToken.toUtf8());
|
||||
|
||||
QNetworkReply* reply = manager.get(request);
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qDebug() << "Error: " << reply->errorString();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return reply->readAll();
|
||||
}
|
||||
|
||||
private:
|
||||
QNetworkAccessManager manager;
|
||||
const QString BASE_URL = "https://us-or-rly101.zwift.com";
|
||||
const QString getAccessToken;
|
||||
};
|
||||
|
||||
class World {
|
||||
public:
|
||||
World(int worldId, const QString& getAccessToken) : worldId(worldId), request(getAccessToken) {}
|
||||
|
||||
QString getPlayers() {
|
||||
return request.json("/relay/worlds/" + QString::number(worldId));
|
||||
}
|
||||
|
||||
QByteArray playerStatus(int playerId) {
|
||||
QByteArray buffer = request.protobuf("/relay/worlds/" + QString::number(worldId) + "/players/" + QString::number(playerId));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
QString player_id() {
|
||||
return request.json("/api/profiles/me");
|
||||
}
|
||||
|
||||
private:
|
||||
int worldId;
|
||||
ZwiftRequest request;
|
||||
};
|
||||
|
||||
class PlayerStateWrapper {
|
||||
public:
|
||||
|
||||
enum TURN_SIGNALS {
|
||||
RIGHT = 0,
|
||||
LEFT = 1,
|
||||
STRAIGHT = 2
|
||||
};
|
||||
|
||||
//PlayerStateWrapper(const zwift_messages::PlayerState& playerState) : playerState(playerState) {}
|
||||
|
||||
int getRideOns() {
|
||||
return (playerState.at(19) >> 24) & 0xfff;
|
||||
}
|
||||
|
||||
bool isTurning() {
|
||||
return (playerState.at(19) & 8) != 0;
|
||||
}
|
||||
|
||||
bool isForward() {
|
||||
return (playerState.at(19) & 4) != 0;
|
||||
}
|
||||
|
||||
int getCourse() {
|
||||
return (playerState.at(19) & 0xff0000) >> 16;
|
||||
}
|
||||
|
||||
int getWorld() {
|
||||
return COURSE_TO_WORLD[getCourse()];
|
||||
}
|
||||
|
||||
int getRoadId() {
|
||||
return (playerState.at(20) & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int getRoadDirection() {
|
||||
return (playerState.at(20) & 0xffff000000) >> 24;
|
||||
}
|
||||
|
||||
TURN_SIGNALS getTurnSignal() {
|
||||
int signalCode = playerState.at(20) & 0x70;
|
||||
if (signalCode == 0x10) {
|
||||
return RIGHT;
|
||||
} else if (signalCode == 0x20) {
|
||||
return LEFT;
|
||||
} else if (signalCode == 0x40) {
|
||||
return STRAIGHT;
|
||||
} else {
|
||||
return STRAIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
int getPowerUp() {
|
||||
return playerState.at(20) & 0xf;
|
||||
}
|
||||
|
||||
bool hasFeatherBoost() {
|
||||
return getPowerUp() == 0;
|
||||
}
|
||||
|
||||
bool hasDraftBoost() {
|
||||
return getPowerUp() == 1;
|
||||
}
|
||||
|
||||
bool hasAeroBoost() {
|
||||
return getPowerUp() == 5;
|
||||
}
|
||||
|
||||
int getCadence() {
|
||||
//return static_cast<int>((playerState.cadenceuhz() * 60) / 1000000);
|
||||
}
|
||||
|
||||
std::string operator()(const std::string& item) {
|
||||
try {
|
||||
//return playerState.GetReflection()->GetString(playerState, playerState.GetDescriptor()->FindFieldByName(item));
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << "Error: " << e.what();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
QMap<int, int> COURSE_TO_WORLD = {{3, 1}, {4, 2}, {5, 3}, {6, 1}};
|
||||
|
||||
enum COURSES {
|
||||
WATOPIA = 3,
|
||||
RICHMOND = 4,
|
||||
LONDON = 5
|
||||
};
|
||||
|
||||
//zwift_messages::PlayerState playerState;
|
||||
QByteArray playerState;
|
||||
};
|
||||
|
||||
#endif // PLAYERSTATEWRAPPER_H
|
||||
116
src/zwift-api/zwift_client_auth.h
Normal file
116
src/zwift-api/zwift_client_auth.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef ZWIFT_CLIENT_AUTH_H
|
||||
#define ZWIFT_CLIENT_AUTH_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QDateTime>
|
||||
|
||||
class AuthToken : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QString username;
|
||||
QString password;
|
||||
QString access_token;
|
||||
qint64 expires_in;
|
||||
QString id_token;
|
||||
qint64 not_before_policy;
|
||||
QString refresh_token;
|
||||
qint64 refresh_expires_in;
|
||||
QString session_state;
|
||||
QString token_type;
|
||||
qint64 access_token_expiration;
|
||||
qint64 refresh_token_expiration;
|
||||
|
||||
AuthToken(const QString& username, const QString& password, QObject* parent = nullptr)
|
||||
: QObject(parent), username(username), password(password) {}
|
||||
|
||||
bool haveValidAccessToken() const {
|
||||
return !access_token.isEmpty() && QDateTime::currentMSecsSinceEpoch() < access_token_expiration;
|
||||
}
|
||||
|
||||
bool haveValidRefreshToken() const {
|
||||
return !refresh_token.isEmpty() && QDateTime::currentMSecsSinceEpoch() < refresh_token_expiration;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString getAccessToken() {
|
||||
if (haveValidAccessToken()) {
|
||||
return access_token;
|
||||
} else {
|
||||
updateTokenData();
|
||||
return access_token;
|
||||
}
|
||||
}
|
||||
|
||||
public slots:
|
||||
void updateTokenData() {
|
||||
if (haveValidRefreshToken()) {
|
||||
QUrl url("https://secure.zwift.com/auth/realms/zwift/tokens/access/codes");
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("refresh_token", refresh_token);
|
||||
query.addQueryItem("grant_type", "refresh_token");
|
||||
query.addQueryItem("client_id", "Zwift_Mobile_Link");
|
||||
url.setQuery(query);
|
||||
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply* reply = networkManager.get(request);
|
||||
connect(reply, &QNetworkReply::finished, [=]() {
|
||||
handleTokenResponse(reply);
|
||||
});
|
||||
} else {
|
||||
QUrl url("https://secure.zwift.com/auth/realms/zwift/tokens/access/codes");
|
||||
QUrlQuery postData;
|
||||
postData.addQueryItem("username", username);
|
||||
postData.addQueryItem("password", password);
|
||||
postData.addQueryItem("grant_type", "password");
|
||||
postData.addQueryItem("client_id", "Zwift_Mobile_Link");
|
||||
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
QNetworkReply* reply = networkManager.post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
|
||||
connect(reply, &QNetworkReply::finished, [=]() {
|
||||
handleTokenResponse(reply);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private slots:
|
||||
void handleTokenResponse(QNetworkReply* reply) {
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QByteArray responseData = reply->readAll();
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(responseData);
|
||||
QJsonObject tokenData = jsonDocument.object();
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
access_token = tokenData["access_token"].toString();
|
||||
expires_in = tokenData["expires_in"].toInt();
|
||||
id_token = tokenData["id_token"].toString();
|
||||
not_before_policy = tokenData["not-before-policy"].toInt();
|
||||
refresh_token = tokenData["refresh_token"].toString();
|
||||
refresh_expires_in = tokenData["refresh_expires_in"].toInt();
|
||||
session_state = tokenData["session_state"].toString();
|
||||
token_type = tokenData["token_type"].toString();
|
||||
|
||||
access_token_expiration = now.toMSecsSinceEpoch() + (expires_in - 5) * 1000;
|
||||
refresh_token_expiration = now.toMSecsSinceEpoch() + (refresh_expires_in - 5) * 1000;
|
||||
|
||||
qDebug() << "Access Token: " << access_token;
|
||||
} else {
|
||||
qDebug() << "Error fetching token: " << reply->errorString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
private:
|
||||
QNetworkAccessManager networkManager;
|
||||
};
|
||||
|
||||
|
||||
#endif // ZWIFT_CLIENT_AUTH_H
|
||||
5489
src/zwift-api/zwift_messages.pb.cc
Normal file
5489
src/zwift-api/zwift_messages.pb.cc
Normal file
File diff suppressed because it is too large
Load Diff
6785
src/zwift-api/zwift_messages.pb.h
Normal file
6785
src/zwift-api/zwift_messages.pb.h
Normal file
File diff suppressed because it is too large
Load Diff
1693
src/zwift-api/zwift_messages.pb.swift
Normal file
1693
src/zwift-api/zwift_messages.pb.swift
Normal file
File diff suppressed because it is too large
Load Diff
153
src/zwift-api/zwift_messages.proto
Normal file
153
src/zwift-api/zwift_messages.proto
Normal file
@@ -0,0 +1,153 @@
|
||||
syntax="proto3";
|
||||
|
||||
message PlayerState {
|
||||
int32 id = 1;
|
||||
int64 worldTime = 2;
|
||||
int32 distance = 3;
|
||||
int32 roadTime = 4;
|
||||
int32 laps = 5;
|
||||
int32 speed = 6;
|
||||
int32 roadPosition = 8;
|
||||
int32 cadenceUHz = 9;
|
||||
int32 heartrate = 11;
|
||||
int32 power = 12;
|
||||
int64 heading = 13;
|
||||
int32 lean = 14;
|
||||
int32 climbing = 15;
|
||||
int32 time = 16;
|
||||
int32 f19 = 19;
|
||||
int32 f20 = 20;
|
||||
int32 progress = 21;
|
||||
int64 customisationId = 22;
|
||||
int32 justWatching = 23;
|
||||
int32 calories = 24;
|
||||
float x = 25;
|
||||
float altitude = 26;
|
||||
float y = 27;
|
||||
int32 watchingRiderId = 28;
|
||||
int32 groupId = 29;
|
||||
int64 sport = 31;
|
||||
}
|
||||
|
||||
message ClientToServer {
|
||||
int32 connected = 1;
|
||||
int32 rider_id = 2;
|
||||
int64 world_time = 3;
|
||||
PlayerState state = 7;
|
||||
int32 seqno = 4;
|
||||
int64 tag8 = 8;
|
||||
int64 tag9 = 9;
|
||||
int64 last_update = 10;
|
||||
int64 tag11 = 11;
|
||||
int64 last_player_update = 12;
|
||||
}
|
||||
|
||||
message SegmentResult {
|
||||
int64 id = 1;
|
||||
int64 rider_id = 2;
|
||||
int64 event_subgroup_id = 6;
|
||||
string first_name = 7;
|
||||
string last_name = 8;
|
||||
string finish_time_str = 10;
|
||||
int64 elapsed_ms = 11;
|
||||
int32 powermeter = 12;
|
||||
int32 weight = 13;
|
||||
int32 power = 15;
|
||||
int32 heartrate = 19;
|
||||
}
|
||||
|
||||
message SegmentResults {
|
||||
int64 world_id = 1;
|
||||
int64 segment_id = 2;
|
||||
int64 event_subgroup_id = 3;
|
||||
repeated SegmentResult segment_results = 4;
|
||||
}
|
||||
|
||||
message UnknownMessage1 {
|
||||
// string firstName=7;
|
||||
// string lastName=8;
|
||||
// string timestamp=17;
|
||||
}
|
||||
|
||||
message UnknownMessage {
|
||||
// int64 tag1=1;
|
||||
// UnknownMessage1 tag4=4;
|
||||
}
|
||||
|
||||
message ServerToClient {
|
||||
int32 tag1 = 1;
|
||||
int32 rider_id = 2;
|
||||
int64 world_time = 3;
|
||||
int32 seqno = 4;
|
||||
repeated PlayerState player_states = 8;
|
||||
repeated UnknownMessage player_updates = 9;
|
||||
int64 tag11 = 11;
|
||||
int64 tag17 = 17;
|
||||
int32 num_msgs = 18;
|
||||
int32 msgnum = 19;
|
||||
}
|
||||
|
||||
message WorldAttributes {
|
||||
int32 world_id = 1;
|
||||
string name = 2;
|
||||
int64 tag3 = 3;
|
||||
int64 tag5 = 4;
|
||||
int64 world_time = 6;
|
||||
int64 clock_time = 7;
|
||||
}
|
||||
|
||||
message WorldAttribute {
|
||||
int64 world_time = 2;
|
||||
}
|
||||
|
||||
message EventSubgroupProtobuf {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
int32 rules = 8;
|
||||
int32 route = 22;
|
||||
int32 laps = 25;
|
||||
int32 startLocation = 29;
|
||||
int32 label = 30;
|
||||
int32 paceType = 31;
|
||||
int32 jerseyHash = 36;
|
||||
}
|
||||
|
||||
message RiderAttributes {
|
||||
int32 f2 = 2;
|
||||
int32 f3 = 3;
|
||||
message AttributeMessage {
|
||||
int32 myId = 1;
|
||||
int32 theirId = 2;
|
||||
string firstName = 3;
|
||||
string lastName = 4;
|
||||
int32 countryCode = 5;
|
||||
}
|
||||
AttributeMessage attributeMessage = 4;
|
||||
int32 theirId = 10;
|
||||
int32 f13 = 13;
|
||||
}
|
||||
|
||||
message Profiles {
|
||||
repeated Profile profiles = 1;
|
||||
}
|
||||
|
||||
message Profile {
|
||||
int32 id = 1;
|
||||
string firstName = 4;
|
||||
string lastName = 5;
|
||||
int32 male = 6;
|
||||
int32 weight = 9;
|
||||
int32 bodyType = 12;
|
||||
int32 countryCode = 34;
|
||||
int32 totalDistance = 35;
|
||||
int32 totalDistanceClimbed = 36;
|
||||
int32 totalTimeInMinutes = 37;
|
||||
int32 totalWattHours = 41;
|
||||
int32 height = 42;
|
||||
int32 totalExperiencePoints = 46;
|
||||
int32 achievementLevel = 49;
|
||||
int32 powerSource = 52;
|
||||
int32 age = 55;
|
||||
string launchedGameClient = 108;
|
||||
int32 currentActivityId = 109;
|
||||
}
|
||||
47
src/zwift-api/zwift_protobuf_layer.swift
Normal file
47
src/zwift-api/zwift_protobuf_layer.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// zwift_protobuf_layer.swift
|
||||
// qdomyoszwift
|
||||
//
|
||||
// Created by Roberto Viola on 30/12/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftProtobuf
|
||||
|
||||
@objc public class zwift_protobuf_layer : NSObject {
|
||||
var player: PlayerState!
|
||||
let SwiftDebug = swiftDebug()
|
||||
|
||||
@objc public func getPlayerState(value: Data) {
|
||||
do {
|
||||
//let hexString = value.map { String(format: "%02x", $0) }.joined()
|
||||
//SwiftDebug.qtDebug("HEX \(hexString)")
|
||||
let decodedInfo = try PlayerState(serializedData: value)
|
||||
player = decodedInfo
|
||||
} catch {
|
||||
SwiftDebug.qtDebug("An error occurred: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func getAltitude() -> Float {
|
||||
return player.altitude
|
||||
}
|
||||
|
||||
@objc public func getDistance() -> Int32 {
|
||||
return player.distance
|
||||
}
|
||||
|
||||
@objc public func getLatitude() -> Float {
|
||||
return player.x
|
||||
}
|
||||
|
||||
@objc public func getLongitude() -> Float {
|
||||
return player.y
|
||||
}
|
||||
|
||||
/*
|
||||
@objc public init() {
|
||||
super.init()
|
||||
}*/
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user