Compare commits

..

15 Commits

Author SHA1 Message Date
Roberto Viola
f2d8bd9dc3 Update PlayerStateWrapper.h 2023-12-30 18:54:37 +00:00
Roberto Viola
f03068189b final build for ios 2023-12-30 19:28:04 +01:00
Roberto Viola
8e166ff6cf works perfectly with zwift! 2023-12-30 18:57:36 +01:00
Roberto Viola
f1d2b5ec40 works on ios! 2023-12-30 18:14:34 +01:00
Roberto Viola
d858eff4cc Create zwift_messages.pb.swift 2023-12-29 18:01:13 +01:00
Roberto Viola
ca4ce00743 getting protodata 2023-12-28 18:49:01 +01:00
Roberto Viola
534d39053e Update PlayerStateWrapper.h 2023-12-28 17:21:31 +01:00
Roberto Viola
8fb3030933 Update main.cpp 2023-12-28 17:03:39 +01:00
Roberto Viola
f43db4fe31 Update project.pbxproj 2023-12-28 16:55:15 +01:00
Roberto Viola
98603ba8b8 fixing build 2023-12-28 16:49:34 +01:00
Roberto Viola
ec85319987 trying without the protobuffer 2023-12-28 16:45:57 +01:00
Roberto Viola
5b9122e337 Create zwift_messages.proto 2023-12-28 15:43:28 +01:00
Roberto Viola
84e27e6db1 protobuf added 2023-12-28 15:43:23 +01:00
Roberto Viola
18543d5d71 adding files 2023-12-28 15:41:48 +01:00
Roberto Viola
76dc3b38b8 Speed on GPX treadmill run is too fast and does not match GPX[BUG] #1870
https://github.com/cagnulein/qdomyos-zwift/issues/1870#issuecomment-1866176352
2023-12-28 11:27:27 +01:00
24 changed files with 14848 additions and 333 deletions

View File

@@ -114,9 +114,6 @@
7EC1321DD83EAAFAA2B7109C /* domyosbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 7944A61A6F17291731CE6F84 /* domyosbike.cpp */; settings = {ATTRIBUTES = (); }; };
8556B13A3D02D52A21FC5E3E /* bluetooth.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = B0BE11FB9531A6AD480B20E7 /* bluetooth.cpp */; settings = {ATTRIBUTES = (); }; };
868B65D0AB5114A4A0D5479E /* qmldbg_messages in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 008F20821C7E4D5F7DB55754 /* qmldbg_messages */; };
8701142A2B14D5A800193FC6 /* moc_eliteariafan.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 870114292B14D5A800193FC6 /* moc_eliteariafan.cpp */; };
8701142D2B14D5C600193FC6 /* eliteariafan.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8701142C2B14D5C600193FC6 /* eliteariafan.cpp */; };
870114302B14D5F400193FC6 /* ios_eliteariafan.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8701142E2B14D5F400193FC6 /* ios_eliteariafan.mm */; };
8703BAEB273C67A90058E206 /* pafersbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8703BAE9273C67A90058E206 /* pafersbike.cpp */; };
8703BAED273C67B60058E206 /* moc_pafersbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8703BAEC273C67B50058E206 /* moc_pafersbike.cpp */; };
87061390286D8B4F00D2446E /* libQt5PositioningQuick.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 8706138F286D8B4F00D2446E /* libQt5PositioningQuick.a */; };
@@ -185,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 */; };
@@ -332,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 */; };
@@ -827,11 +831,6 @@
867187CB3CB3703D1925C88A /* fit_weather_conditions_mesg_listener.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fit_weather_conditions_mesg_listener.hpp; path = "/Users/cagnulein/qdomyos-zwift/src/fit-sdk/fit_weather_conditions_mesg_listener.hpp"; sourceTree = "<absolute>"; };
86DD72842A64993F31E31719 /* fit_ant_rx_mesg_listener.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fit_ant_rx_mesg_listener.hpp; path = "/Users/cagnulein/qdomyos-zwift/src/fit-sdk/fit_ant_rx_mesg_listener.hpp"; sourceTree = "<absolute>"; };
86F10E1AE2D47520E65C0543 /* fit_dive_summary_mesg_listener.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fit_dive_summary_mesg_listener.hpp; path = "/Users/cagnulein/qdomyos-zwift/src/fit-sdk/fit_dive_summary_mesg_listener.hpp"; sourceTree = "<absolute>"; };
870114292B14D5A800193FC6 /* moc_eliteariafan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_eliteariafan.cpp; sourceTree = "<group>"; };
8701142B2B14D5C600193FC6 /* eliteariafan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = eliteariafan.h; path = ../src/eliteariafan.h; sourceTree = "<group>"; };
8701142C2B14D5C600193FC6 /* eliteariafan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = eliteariafan.cpp; path = ../src/eliteariafan.cpp; sourceTree = "<group>"; };
8701142E2B14D5F400193FC6 /* ios_eliteariafan.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ios_eliteariafan.mm; path = ../src/ios/ios_eliteariafan.mm; sourceTree = "<group>"; };
8701142F2B14D5F400193FC6 /* ios_eliteariafan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ios_eliteariafan.h; path = ../src/ios/ios_eliteariafan.h; sourceTree = "<group>"; };
8703BAE9273C67A90058E206 /* pafersbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pafersbike.cpp; path = ../src/pafersbike.cpp; sourceTree = "<group>"; };
8703BAEA273C67A90058E206 /* pafersbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pafersbike.h; path = ../src/pafersbike.h; sourceTree = "<group>"; };
8703BAEC273C67B50058E206 /* moc_pafersbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_pafersbike.cpp; sourceTree = "<group>"; };
@@ -917,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>"; };
@@ -1141,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>"; };
@@ -1680,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 */,
@@ -1688,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 */,
@@ -1701,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 */,
@@ -1925,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 */,
@@ -2297,6 +2310,7 @@
C8CE72E7B224D8B886614E3F /* domyosbike.h */,
8710707229C4A5E70094D0F3 /* GarminConnect.swift */,
87A2E0202B2B024200E6168F /* swiftDebug.h */,
8730A3912B404159007E336D /* zwift_protobuf_layer.swift */,
);
name = Sources;
sourceTree = "<group>";
@@ -2824,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";
@@ -2899,6 +2918,9 @@
Base,
);
mainGroup = E8C543AB96796ECAA2E65C57 /* qdomyoszwift */;
packageReferences = (
8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */,
);
productRefGroup = FE0A091FDBFB3E9C31B7A1BD /* Products */;
projectDirPath = "";
projectRoot = "";
@@ -3044,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 */,
@@ -3079,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 */,
@@ -3144,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 */,
@@ -3291,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 */,
@@ -4516,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 */;
}

View File

@@ -49,9 +49,6 @@ public class QZAdbRemote implements DeviceConnectionListener {
private static QZAdbRemote INSTANCE;
private static String receiveBuffer = "";
private static String receiveOldBuffer = "";
public static QZAdbRemote getInstance() {
if(INSTANCE == null) {
INSTANCE = new QZAdbRemote();
@@ -96,6 +93,7 @@ public class QZAdbRemote implements DeviceConnectionListener {
@Override
public void receivedData(DeviceConnection devConn, byte[] data, int offset, int length) {
Log.i(LOG_TAG, data.toString());
}
@Override
@@ -105,8 +103,7 @@ public class QZAdbRemote implements DeviceConnectionListener {
@Override
public void consoleUpdated(DeviceConnection devConn, ConsoleBuffer console) {
receiveBuffer += new String(console.buffer);
Log.i(LOG_TAG, new String(console.buffer));
}
@@ -198,12 +195,6 @@ public class QZAdbRemote implements DeviceConnectionListener {
}
}
static public String getReceiveData() {
receiveOldBuffer = receiveBuffer;
receiveBuffer = "";
return receiveOldBuffer;
}
static public void sendCommand(String command) {
Log.d(LOG_TAG, "sendCommand " + ADBConnected + " " + command);
if(ADBConnected) {

View File

@@ -3,7 +3,7 @@ package com.cgutman.androidremotedebugger.console;
import android.widget.TextView;
public class ConsoleBuffer {
public char[] buffer;
private char[] buffer;
private int amountPopulated;
public ConsoleBuffer(int bufferSize)

View File

@@ -5259,6 +5259,12 @@ QString homeform::copyAndroidContentsURI(QUrl file, QString subfolder) {
QFileInfo f(fileNameLocal);
QString filename = f.fileName();
QFile fileFile(QQmlFile::urlToLocalFileOrQrc(file));
// android <14 fallback
if(fileNameLocal.length() == 0) {
qDebug() << "android <14 fallback" << fileNameLocal << filename << file.fileName();
filename = file.fileName();
}
QString dest = getWritableAppDir() + subfolder + "/" + filename;
qDebug() << file.fileName() << fileNameLocal << filename;
QFile::remove(dest);

View File

@@ -62,11 +62,18 @@ class lockscreen {
//adb
void adb_connect(const char* IP);
int adb_sendcommand(const char* command, unsigned char** buffer);
void adb_sendcommand(const char* command);
// 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

View File

@@ -10,7 +10,6 @@
#include <QDebug>
#include "ios/AdbClient.h"
#include "ios/ios_eliteariafan.h"
#import <dispatch/dispatch.h>
@class virtualbike_ios_swift;
@class virtualbike_zwift;
@@ -30,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];
}
@@ -38,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];
}
@@ -271,9 +273,6 @@ void lockscreen::debug(const char* debugstring) {
}
void lockscreen::adb_connect(const char* IP) {
qDebug() << "adb_connect" << IP << _adb;
if(_adb == 0) return;
[_adb connect:[NSString stringWithCString:IP encoding:NSASCIIStringEncoding] didResponse:^(BOOL succ, NSString *result) {
@@ -283,48 +282,16 @@ void lockscreen::adb_connect(const char* IP) {
}];
}
int lockscreen::adb_sendcommand(const char* command, unsigned char** outBuffer) {
qDebug() << "adb_sendcommand" << command << _adb;
if(_adb == 0) return -1; // or some error code
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
qDebug() << "adb_sendcommand after semaphore";
__block int resultStatus = 0; // Use this to store the result status
__block NSUInteger length = 0;
void lockscreen::adb_sendcommand(const char* command) {
if(_adb == 0) return;
[_adb shell:[NSString stringWithCString:command encoding:NSASCIIStringEncoding] didResponse:^(BOOL succ, NSString *result) {
qDebug() << result;
NSUInteger length = [result lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
// Allocate memory for the unsigned char*
*outBuffer = (unsigned char *)malloc(length + 1);
// Copy the string into the buffer
if (*outBuffer) {
BOOL resultCopy = [result getCString:(char *)*outBuffer maxLength:length + 1 encoding:NSUTF8StringEncoding];
if (!resultCopy) {
// Handle the error if the string couldn't be copied
free(*outBuffer);
*outBuffer = NULL;
resultStatus = -2; // or some error code
}
} else {
resultStatus = -3; // or some error code
}
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return length;
}
void lockscreen::eliteAriaFan() {
ios_eliteAriaFan = [[ios_eliteariafan alloc] init];
}
@@ -334,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

View File

@@ -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

View File

@@ -19,20 +19,7 @@ nordictrackifitadbbikeLogcatAdbThread::nordictrackifitadbbikeLogcatAdbThread(QSt
void nordictrackifitadbbikeLogcatAdbThread::run() {
QSettings settings;
QString ip = settings.value(QZSettings::tdf_10_ip, QZSettings::default_tdf_10_ip).toString();
#ifdef Q_OS_ANDROID
QAndroidJniObject IP = QAndroidJniObject::fromString(ip).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "createConnection",
"(Ljava/lang/String;Landroid/content/Context;)V",
IP.object<jstring>(), QtAndroid::androidContext().object());
#elif defined Q_OS_WIN
runAdbCommand("connect " + ip);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h = new lockscreen();
h->adb_connect(ip.toStdString().c_str());
#endif
#endif
while (1) {
runAdbTailCommand("logcat");
@@ -56,32 +43,10 @@ QString nordictrackifitadbbikeLogcatAdbThread::runAdbCommand(QString command) {
emit debug("adb << OUT " + out);
emit debug("adb << ERR" + err);
return out;
#elif defined Q_OS_ANDROID
qDebug() << "adbLogCat >> " << command;
QAndroidJniObject c = QAndroidJniObject::fromString(command).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
c.object<jstring>());
QThread:msleep(100);
QAndroidJniObject recv = QAndroidJniObject::callStaticObjectMethod<jstring>(
"org/cagnulen/qdomyoszwift/QZAdbRemote", "getReceiveData");
QString r = recv.toString();
return r;
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
qDebug() << "adb >> " << command;
unsigned char* tailMemoryBuffer = nullptr;
int size = h->adb_sendcommand(command.toStdString().c_str(), &tailMemoryBuffer);
if(tailMemoryBuffer) {
QString output = QString::fromUtf8((const char*)tailMemoryBuffer);
delete tailMemoryBuffer;
return output;
}
return "";
#else
QString out;
#endif
#endif
return out;
}
bool nordictrackifitadbbikeLogcatAdbThread::runCommand(QString command) {
@@ -134,86 +99,6 @@ void nordictrackifitadbbikeLogcatAdbThread::runAdbTailCommand(QString command) {
emit debug("adbLogCat >> " + command);
process->start("adb/adb.exe", QStringList(command.split(' ')));
process->waitForFinished(-1);
#elif defined Q_OS_ANDROID
qDebug() << "adbLogCat >> " << command;
QAndroidJniObject c = QAndroidJniObject::fromString(command).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
c.object<jstring>());
QString r = "";
do {
QAndroidJniObject recv = QAndroidJniObject::callStaticObjectMethod<jstring>(
"org/cagnulen/qdomyoszwift/QZAdbRemote", "getReceiveData");
r = recv.toString();
QString output = r;
QStringList lines = output.split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts);
bool wattFound = false;
bool hrmFound = false;
foreach (QString line, lines) {
if (line.contains("Changed KPH")) {
emit debug(line);
speed = line.split(' ').last().toDouble();
} else if (line.contains("Changed Grade")) {
emit debug(line);
inclination = line.split(' ').last().toDouble();
} else if (line.contains("Changed Watts")) {
emit debug(line);
watt = line.split(' ').last().toDouble();
wattFound = true;
} else if (line.contains("HeartRateDataUpdate")) {
emit debug(line);
QStringList splitted = line.split(' ', Qt::SkipEmptyParts);
if (splitted.length() > 14) {
hrm = splitted[14].toInt();
hrmFound = true;
}
}
}
emit onSpeedInclination(speed, inclination);
if (wattFound)
emit onWatt(watt);
if (hrmFound)
emit onHRM(hrm);
} while (r.length());
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
qDebug() << "adbLogCat >> " << command;
unsigned char* tailMemoryBuffer = nullptr;
int size = h->adb_sendcommand("logcat", &tailMemoryBuffer);
if(tailMemoryBuffer) {
QString output = QString::fromUtf8((const char*)tailMemoryBuffer);
QStringList lines = output.split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts);
bool wattFound = false;
bool hrmFound = false;
foreach (QString line, lines) {
if (line.contains("Changed KPH")) {
emit debug(line);
speed = line.split(' ').last().toDouble();
} else if (line.contains("Changed Grade")) {
emit debug(line);
inclination = line.split(' ').last().toDouble();
} else if (line.contains("Changed Watts")) {
emit debug(line);
watt = line.split(' ').last().toDouble();
wattFound = true;
} else if (line.contains("HeartRateDataUpdate")) {
emit debug(line);
QStringList splitted = line.split(' ', Qt::SkipEmptyParts);
if (splitted.length() > 14) {
hrm = splitted[14].toInt();
hrmFound = true;
}
}
}
emit onSpeedInclination(speed, inclination);
if (wattFound)
emit onWatt(watt);
if (hrmFound)
emit onHRM(hrm);
delete tailMemoryBuffer;
}
#endif
#endif
}
@@ -269,6 +154,12 @@ nordictrackifitadbbike::nordictrackifitadbbike(bool noWriteResistance, bool noHe
// ********************************************************************************************************
if (nordictrack_ifit_adb_remote) {
#ifdef Q_OS_ANDROID
QAndroidJniObject IP = QAndroidJniObject::fromString(ip).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "createConnection",
"(Ljava/lang/String;Landroid/content/Context;)V",
IP.object<jstring>(), QtAndroid::androidContext().object());
#elif defined Q_OS_WIN
logcatAdbThread = new nordictrackifitadbbikeLogcatAdbThread("logcatAdbThread");
/*connect(logcatAdbThread, &nordictrackifitadbbikeLogcatAdbThread::onSpeedInclination, this,
&nordictrackifitadbbike::onSpeedInclination);
@@ -277,6 +168,11 @@ nordictrackifitadbbike::nordictrackifitadbbike(bool noWriteResistance, bool noHe
connect(logcatAdbThread, &nordictrackifitadbbikeLogcatAdbThread::onHRM, this, &nordictrackifitadbbike::onHRM);
connect(logcatAdbThread, &nordictrackifitadbbikeLogcatAdbThread::debug, this, &nordictrackifitadbbike::debug);
logcatAdbThread->start();
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_connect(ip.toStdString().c_str());
#endif
#endif
}
}
@@ -396,9 +292,19 @@ void nordictrackifitadbbike::processPendingDatagrams() {
lastCommand = "input swipe " + QString::number(x1) + " " + QString::number(y1Resistance) + " " +
QString::number(x1) + " " + QString::number(y2) + " 200";
qDebug() << " >> " + lastCommand;
#ifdef Q_OS_ANDROID
QAndroidJniObject command = QAndroidJniObject::fromString(lastCommand).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
command.object<jstring>());
#elif defined(Q_OS_WIN)
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_sendcommand(lastCommand.toStdString().c_str());
#endif
#endif
}
}
@@ -431,10 +337,19 @@ void nordictrackifitadbbike::processPendingDatagrams() {
lastCommand = "input swipe " + QString::number(x1) + " " + QString::number(y1Resistance) + " " +
QString::number(x1) + " " + QString::number(y2) + " 200";
qDebug() << " >> " + lastCommand;
#ifdef Q_OS_ANDROID
QAndroidJniObject command = QAndroidJniObject::fromString(lastCommand).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
command.object<jstring>());
#elif defined(Q_OS_WIN)
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_sendcommand(lastCommand.toStdString().c_str());
#endif
#endif
// this bike has both inclination and resistance, let's try to handle both
if(freemotion_coachbike_b22_7) {
int x1 = 75;
@@ -444,9 +359,19 @@ void nordictrackifitadbbike::processPendingDatagrams() {
lastCommand = "input swipe " + QString::number(x1) + " " + QString::number(y1Resistance) + " " +
QString::number(x1) + " " + QString::number(y2) + " 200";
qDebug() << " >> " + lastCommand;
#ifdef Q_OS_ANDROID
QAndroidJniObject command = QAndroidJniObject::fromString(lastCommand).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
command.object<jstring>());
#elif defined(Q_OS_WIN)
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_sendcommand(lastCommand.toStdString().c_str());
#endif
#endif
}
}
}

View File

@@ -53,12 +53,8 @@ class nordictrackifitadbbikeLogcatAdbThread : public QThread {
QDateTime date;
QString name;
};
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif
void runAdbTailCommand(QString command);
void runAdbTailCommand(QString command);
};
class nordictrackifitadbbike : public bike {
@@ -103,7 +99,7 @@ class nordictrackifitadbbike : public bike {
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif
signals:
void disconnected();
void debug(QString string);

View File

@@ -20,29 +20,20 @@ nordictrackifitadbtreadmillLogcatAdbThread::nordictrackifitadbtreadmillLogcatAdb
void nordictrackifitadbtreadmillLogcatAdbThread::run() {
QSettings settings;
QString ip = settings.value(QZSettings::nordictrack_2950_ip, QZSettings::default_nordictrack_2950_ip).toString();
#ifdef Q_OS_ANDROID
QAndroidJniObject IP = QAndroidJniObject::fromString(ip).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "createConnection",
"(Ljava/lang/String;Landroid/content/Context;)V",
IP.object<jstring>(), QtAndroid::androidContext().object());
#elif defined Q_OS_WIN
runAdbCommand("connect " + ip);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h = new lockscreen();
h->adb_connect(ip.toStdString().c_str());
#endif
#endif
while (1) {
while (!stop)
{
runAdbTailCommand("logcat");
#ifndef Q_OS_WINDOWS
if(adbCommandPending.length() != 0) {
runAdbCommand(adbCommandPending);
adbCommandPending = "";
}
msleep(100);
msleep(100);
#endif
}
}
QString nordictrackifitadbtreadmillLogcatAdbThread::runAdbCommand(QString command) {
@@ -57,32 +48,10 @@ QString nordictrackifitadbtreadmillLogcatAdbThread::runAdbCommand(QString comman
emit debug("adb << OUT " + out);
emit debug("adb << ERR" + err);
return out;
#elif defined Q_OS_ANDROID
qDebug() << "adbLogCat >> " << command;
QAndroidJniObject c = QAndroidJniObject::fromString(command).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
c.object<jstring>());
QThread:msleep(100);
QAndroidJniObject recv = QAndroidJniObject::callStaticObjectMethod<jstring>(
"org/cagnulen/qdomyoszwift/QZAdbRemote", "getReceiveData");
QString r = recv.toString();
return r;
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
qDebug() << "adb >> " << command;
unsigned char* tailMemoryBuffer = nullptr;
int size = h->adb_sendcommand(command.toStdString().c_str(), &tailMemoryBuffer);
if(tailMemoryBuffer) {
QString output = QString::fromUtf8((const char*)tailMemoryBuffer);
delete tailMemoryBuffer;
return output;
}
return "";
#else
QString out;
#endif
#endif
return out;
}
bool nordictrackifitadbtreadmillLogcatAdbThread::runCommand(QString command) {
@@ -135,87 +104,6 @@ void nordictrackifitadbtreadmillLogcatAdbThread::runAdbTailCommand(QString comma
emit debug("adbLogCat >> " + command);
process->start("adb/adb.exe", QStringList(command.split(' ')));
process->waitForFinished(-1);
#elif defined Q_OS_ANDROID
qDebug() << "adbLogCat >> " << command;
QAndroidJniObject c = QAndroidJniObject::fromString(command).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote",
"sendCommand", "(Ljava/lang/String;)V",
c.object<jstring>());
QString r = "";
do {
QAndroidJniObject recv = QAndroidJniObject::callStaticObjectMethod<jstring>(
"org/cagnulen/qdomyoszwift/QZAdbRemote", "getReceiveData");
r = recv.toString();
qDebug() << " << " << r;
QString output = r;
QStringList lines = output.split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts);
bool wattFound = false;
bool hrmFound = false;
foreach (QString line, lines) {
if (line.contains("Changed KPH")) {
emit debug(line);
speed = line.split(' ').last().toDouble();
} else if (line.contains("Changed Grade")) {
emit debug(line);
inclination = line.split(' ').last().toDouble();
} else if (line.contains("Changed Watts")) {
emit debug(line);
watt = line.split(' ').last().toDouble();
wattFound = true;
} else if (line.contains("HeartRateDataUpdate")) {
emit debug(line);
QStringList splitted = line.split(' ', Qt::SkipEmptyParts);
if (splitted.length() > 14) {
hrm = splitted[14].toInt();
hrmFound = true;
}
}
}
emit onSpeedInclination(speed, inclination);
if (wattFound)
emit onWatt(watt);
if (hrmFound)
emit onHRM(hrm);
} while (r.length());
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
qDebug() << "adbLogCat >> " << command;
unsigned char* tailMemoryBuffer = nullptr;
int size = h->adb_sendcommand("logcat", &tailMemoryBuffer);
if(tailMemoryBuffer) {
QString output = QString::fromUtf8((const char*)tailMemoryBuffer);
QStringList lines = output.split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts);
bool wattFound = false;
bool hrmFound = false;
foreach (QString line, lines) {
if (line.contains("Changed KPH")) {
emit debug(line);
speed = line.split(' ').last().toDouble();
} else if (line.contains("Changed Grade")) {
emit debug(line);
inclination = line.split(' ').last().toDouble();
} else if (line.contains("Changed Watts")) {
emit debug(line);
watt = line.split(' ').last().toDouble();
wattFound = true;
} else if (line.contains("HeartRateDataUpdate")) {
emit debug(line);
QStringList splitted = line.split(' ', Qt::SkipEmptyParts);
if (splitted.length() > 14) {
hrm = splitted[14].toInt();
hrmFound = true;
}
}
}
emit onSpeedInclination(speed, inclination);
if (wattFound)
emit onWatt(watt);
if (hrmFound)
emit onHRM(hrm);
delete tailMemoryBuffer;
}
#endif
#endif
}
@@ -243,14 +131,38 @@ nordictrackifitadbtreadmill::nordictrackifitadbtreadmill(bool noWriteResistance,
QString ip = settings.value(QZSettings::nordictrack_2950_ip, QZSettings::default_nordictrack_2950_ip).toString();
refresh->start(200ms);
logcatAdbThread = new nordictrackifitadbtreadmillLogcatAdbThread("logcatAdbThread");
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::onSpeedInclination, this,
&nordictrackifitadbtreadmill::onSpeedInclination);
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::onWatt, this,
&nordictrackifitadbtreadmill::onWatt);
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::debug, this,
&nordictrackifitadbtreadmill::debug);
logcatAdbThread->start();
{
socket = new QUdpSocket(this);
bool result = socket->bind(QHostAddress::AnyIPv4, 8002);
qDebug() << result;
processPendingDatagrams();
connect(socket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
}
#ifdef Q_OS_WIN32
{
logcatAdbThread = new nordictrackifitadbtreadmillLogcatAdbThread("logcatAdbThread");
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::onSpeedInclination, this,
&nordictrackifitadbtreadmill::onSpeedInclination);
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::onWatt, this,
&nordictrackifitadbtreadmill::onWatt);
connect(logcatAdbThread, &nordictrackifitadbtreadmillLogcatAdbThread::debug, this,
&nordictrackifitadbtreadmill::debug);
logcatAdbThread->start();
}
#endif
if (nordictrack_ifit_adb_remote) {
#ifdef Q_OS_ANDROID
QAndroidJniObject IP = QAndroidJniObject::fromString(ip).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "createConnection",
"(Ljava/lang/String;Landroid/content/Context;)V",
IP.object<jstring>(), QtAndroid::androidContext().object());
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_connect(ip.toStdString().c_str());
#endif
#endif
}
initRequest = true;
@@ -371,9 +283,18 @@ void nordictrackifitadbtreadmill::processPendingDatagrams() {
lastCommand = "input swipe " + QString::number(x1) + " " + QString::number(y1Speed) + " " +
QString::number(x1) + " " + QString::number(y2) + " 200";
qDebug() << " >> " + lastCommand;
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#ifdef Q_OS_ANDROID
QAndroidJniObject command = QAndroidJniObject::fromString(lastCommand).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "sendCommand",
"(Ljava/lang/String;)V", command.object<jstring>());
#elif defined(Q_OS_WIN)
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_sendcommand(lastCommand.toStdString().c_str());
#endif
#endif
requestSpeed = -1;
} else if (currentRequestInclination != -100) {
requestInclination = inc;
@@ -391,10 +312,18 @@ void nordictrackifitadbtreadmill::processPendingDatagrams() {
lastCommand = "input swipe " + QString::number(x1) + " " + QString::number(y1Inclination) + " " +
QString::number(x1) + " " + QString::number(y2) + " 200";
qDebug() << " >> " + lastCommand;
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#ifdef Q_OS_ANDROID
QAndroidJniObject command = QAndroidJniObject::fromString(lastCommand).object<jstring>();
QAndroidJniObject::callStaticMethod<void>("org/cagnulen/qdomyoszwift/QZAdbRemote", "sendCommand",
"(Ljava/lang/String;)V", command.object<jstring>());
#elif defined(Q_OS_WIN)
if (logcatAdbThread)
logcatAdbThread->runCommand("shell " + lastCommand);
#elif defined Q_OS_IOS
#ifndef IO_UNDER_QT
h->adb_sendcommand(lastCommand.toStdString().c_str());
#endif
#endif
requestInclination = -100;
}
}

View File

@@ -39,24 +39,18 @@ class nordictrackifitadbtreadmillLogcatAdbThread : public QThread {
void onSpeedInclination(double speed, double inclination);
void debug(QString message);
void onWatt(double watt);
void onHRM(int hrm);
private:
QString adbCommandPending = "";
double speed = 0;
double inclination = 0;
double watt = 0;
int hrm = 0;
QString name;
struct adbfile {
QDateTime date;
QString name;
};
#ifdef Q_OS_IOS
lockscreen *h = 0;
#endif
QString runAdbCommand(QString command);
void runAdbTailCommand(QString command);
};

View File

@@ -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 \

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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;
}

View 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()
}*/
}