Преглед изворни кода

use submodules

use Loop submodules (WIP)
Pierre L пре 2 година
родитељ
комит
6b189aa318
31 измењених фајлова са 547 додато и 673 уклоњено
  1. 36 0
      .gitmodules
  2. 1 0
      CGMBLEKit
  3. 4 80
      FreeAPS.xcodeproj/project.pbxproj
  4. 211 1
      FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme
  5. 27 0
      FreeAPS.xcworkspace/contents.xcworkspacedata
  6. 83 67
      FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved
  7. 22 1
      FreeAPS/Sources/APS/CGM/AppGroupSource.swift
  8. 0 119
      FreeAPS/Sources/APS/CGM/Calibrations/CalibrationService.swift
  9. 144 61
      FreeAPS/Sources/APS/CGM/LibreTransmitterSource.swift
  10. 0 18
      FreeAPS/Sources/APS/Extensions/BloodGlucoseExtensions.swift
  11. 0 1
      FreeAPS/Sources/Modules/CGM/CGMStateModel.swift
  12. 1 1
      FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift
  13. 10 0
      FreeAPS/Sources/Modules/CGM/View/CGMSetupView.swift
  14. 0 13
      FreeAPS/Sources/Modules/Calibrations/CalibrationsDataFlow.swift
  15. 0 3
      FreeAPS/Sources/Modules/Calibrations/CalibrationsProvider.swift
  16. 0 73
      FreeAPS/Sources/Modules/Calibrations/CalibrationsStateModel.swift
  17. 0 60
      FreeAPS/Sources/Modules/Calibrations/View/CalibrationsChart.swift
  18. 0 108
      FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift
  19. 0 5
      FreeAPS/Sources/Modules/LibreConfig/LibreConfigDataFlow.swift
  20. 0 3
      FreeAPS/Sources/Modules/LibreConfig/LibreConfigProvider.swift
  21. 0 17
      FreeAPS/Sources/Modules/LibreConfig/LibreConfigStateModel.swift
  22. 0 36
      FreeAPS/Sources/Modules/LibreConfig/View/LibreConfigRootView.swift
  23. 0 6
      FreeAPS/Sources/Router/Screen.swift
  24. 1 0
      G7SensorKit
  25. 1 0
      LibreTransmitter
  26. 1 0
      LoopKit
  27. 1 0
      MinimedKit
  28. 1 0
      OmniBLE
  29. 1 0
      OmniKit
  30. 1 0
      RileyLinkKit
  31. 1 0
      dexcom-share-client-swift

+ 36 - 0
.gitmodules

@@ -0,0 +1,36 @@
+[submodule "LoopKit"]
+	path = LoopKit
+	url = https://github.com/LoopKit/LoopKit.git
+	branch = dev
+[submodule "CGMBLEKit"]
+	path = CGMBLEKit
+	url = https://github.com/LoopKit/CGMBLEKit.git
+	branch = dev
+[submodule "dexcom-share-client-swift"]
+	path = dexcom-share-client-swift
+	url = https://github.com/LoopKit/dexcom-share-client-swift.git
+	branch = dev
+[submodule "RileyLinkKit"]
+	path = RileyLinkKit
+	url = https://github.com/LoopKit/RileyLinkKit
+	branch = dev
+[submodule "OmniBLE"]
+	path = OmniBLE
+	url = https://github.com/LoopKit/OmniBLE.git
+	branch = dev
+[submodule "G7SensorKit"]
+	path = G7SensorKit
+	url = https://github.com/LoopKit/G7SensorKit.git
+	branch = main
+[submodule "OmniKit"]
+	path = OmniKit
+	url = https://github.com/LoopKit/OmniKit.git
+	branch = main
+[submodule "MinimedKit"]
+	path = MinimedKit
+	url = https://github.com/LoopKit/MinimedKit.git
+	branch = main
+[submodule "LibreTransmitter"]
+	path = LibreTransmitter
+	url = https://github.com/LoopKit/LibreTransmitter.git
+	branch = main

+ 1 - 0
CGMBLEKit

@@ -0,0 +1 @@
+Subproject commit 4eb3c940b0e99ae2715fc6462babd2597d46a845

+ 4 - 80
FreeAPS.xcodeproj/project.pbxproj

@@ -59,7 +59,6 @@
 		2BE9A6FA20875F6F4F9CD461 /* PumpSettingsEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97F14812C1AFED3621165A5 /* PumpSettingsEditorProvider.swift */; };
 		3083261C4B268E353F36CD0B /* AutotuneConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DCCCCE633F5E98E41B0CD3C /* AutotuneConfigDataFlow.swift */; };
 		3171D2818C7C72CD1584BB5E /* NotificationsConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2C6489D29ECCCAD78E0721 /* NotificationsConfigStateModel.swift */; };
-		320D030F724170A637F06D50 /* CalibrationsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 212E8BFE6D66EE65AA26A114 /* CalibrationsProvider.swift */; };
 		33E198D3039045D98C3DC5D4 /* AddCarbsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E7C997E56DAF8D28D09014 /* AddCarbsStateModel.swift */; };
 		3811DE0B25C9D32F00A708ED /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3811DE0725C9D32E00A708ED /* BaseView.swift */; };
 		3811DE0C25C9D32F00A708ED /* BaseProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3811DE0825C9D32F00A708ED /* BaseProvider.swift */; };
@@ -117,8 +116,6 @@
 		385CEA8225F23DFD002D6D5B /* NightscoutStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */; };
 		385CEAC125F2EA52002D6D5B /* Announcement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEAC025F2EA52002D6D5B /* Announcement.swift */; };
 		385CEAC425F2F154002D6D5B /* AnnouncementsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEAC325F2F154002D6D5B /* AnnouncementsStorage.swift */; };
-		3862CC05273D152B00BF832C /* CalibrationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3862CC04273D152B00BF832C /* CalibrationService.swift */; };
-		3862CC1F273FDC9200BF832C /* CalibrationsChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3862CC1E273FDC9200BF832C /* CalibrationsChart.swift */; };
 		3862CC2E2743F9F700BF832C /* CalendarManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3862CC2D2743F9F700BF832C /* CalendarManager.swift */; };
 		386A124F271707F000DDC61C /* DexcomSourceG6.swift in Sources */ = {isa = PBXBuildFile; fileRef = 386A124E271707F000DDC61C /* DexcomSourceG6.swift */; };
 		3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3870FF4225EC13F40088248F /* BloodGlucose.swift */; };
@@ -246,7 +243,6 @@
 		53F2382465BF74DB1A967C8B /* PumpConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8630D58BDAD6D9C650B9B39 /* PumpConfigProvider.swift */; };
 		5BFA1C2208114643B77F8CEB /* AddTempTargetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE53A13D26F101B332EFFC8 /* AddTempTargetProvider.swift */; };
 		5D16287A969E64D18CE40E44 /* PumpConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F60E97100041040446F44E7 /* PumpConfigStateModel.swift */; };
-		61962FCAF8A2D222553AC5A3 /* LibreConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A5B83E7967C38F7CBD883C /* LibreConfigDataFlow.swift */; };
 		63E890B4D951EAA91C071D5C /* BasalProfileEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFF91130F2FCCC7EBBA11AD /* BasalProfileEditorStateModel.swift */; };
 		642F76A05A4FF530463A9FD0 /* NightscoutConfigRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8782B44544F38F2B2D82C38E /* NightscoutConfigRootView.swift */; };
 		6632A0DC746872439A858B44 /* ISFEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BDA519C9B890FD9A5DFCF3 /* ISFEditorDataFlow.swift */; };
@@ -254,7 +250,6 @@
 		69B9A368029F7EB39F525422 /* CREditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA5E04A2761F6EEA6568E1 /* CREditorStateModel.swift */; };
 		6B1F539F9FF75646D1606066 /* SnoozeDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36A708CDB546692C2230B385 /* SnoozeDataFlow.swift */; };
 		6B9625766B697D1C98E455A2 /* PumpSettingsEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72778B68C3004F71F6E79BDC /* PumpSettingsEditorStateModel.swift */; };
-		6EADD581738D64431902AC0A /* LibreConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EBA7C03C26FCC67E16D798 /* LibreConfigProvider.swift */; };
 		6FFAE524D1D9C262F2407CAE /* SnoozeProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CAE81192B118804DCD23034 /* SnoozeProvider.swift */; };
 		711C0CB42CAABE788916BC9D /* ManualTempBasalDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96653287EDB276A111288305 /* ManualTempBasalDataFlow.swift */; };
 		72F1BD388F42FCA6C52E4500 /* ConfigEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44080E4709E3AE4B73054563 /* ConfigEditorProvider.swift */; };
@@ -265,8 +260,6 @@
 		891DECF7BC20968D7F566161 /* AutotuneConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EF98E22A39CD656A230704 /* AutotuneConfigProvider.swift */; };
 		8B759CFCF47B392BB365C251 /* BasalProfileEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67F94DD2853CF42BA4E30616 /* BasalProfileEditorDataFlow.swift */; };
 		8BC2F5A29AD1ED08AC0EE013 /* AddTempTargetRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9AAB83FB6C3B41EFD1846A0 /* AddTempTargetRootView.swift */; };
-		903D18976088B09110BCBE29 /* LibreConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68CDC1E5C438D1BEAD4CF24 /* LibreConfigStateModel.swift */; };
-		9050F378F0063C064D7FFC86 /* LibreConfigRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC210C0F3CB6D3C86E5DED4E /* LibreConfigRootView.swift */; };
 		919DBD08F13BAFB180DF6F47 /* AddTempTargetStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C3B5FD881CA45DFDEE0EDA9 /* AddTempTargetStateModel.swift */; };
 		9702FF92A09C53942F20D7EA /* TargetsEditorRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DD795BA46B193644D48138C /* TargetsEditorRootView.swift */; };
 		9825E5E923F0B8FA80C8C7C7 /* NightscoutConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A48AE3AC813A49A517846A /* NightscoutConfigStateModel.swift */; };
@@ -277,11 +270,9 @@
 		A33352ED40476125EBAC6EE0 /* CREditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E22146D3DF4853786C78132 /* CREditorDataFlow.swift */; };
 		A6F097A14CAAE0CE0D11BE1B /* AddCarbsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E62C9757B2F95431B5DC0 /* AddCarbsProvider.swift */; };
 		AD3D2CD42CD01B9EB8F26522 /* PumpConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF65DA88F972B56090AD6AC3 /* PumpConfigDataFlow.swift */; };
-		B7C465E9472624D8A2BE2A6A /* CalibrationsDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA241FB1663EC96FDBE64C8A /* CalibrationsDataFlow.swift */; };
 		B958F1B72BA0711600484851 /* MKRingProgressView in Frameworks */ = {isa = PBXBuildFile; productRef = B958F1B62BA0711600484851 /* MKRingProgressView */; };
 		B9CAAEFC2AE70836000F68BC /* branch.txt in Resources */ = {isa = PBXBuildFile; fileRef = B9CAAEFB2AE70836000F68BC /* branch.txt */; };
 		BA00D96F7B2FF169A06FB530 /* CGMStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C018D1680307A31C9ED7120 /* CGMStateModel.swift */; };
-		BA90041DC8991147E5C8C3AA /* CalibrationsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500371C09F54F89A97D65FDB /* CalibrationsRootView.swift */; };
 		BD2B464E0745FBE7B79913F4 /* NightscoutConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */; };
 		BF1667ADE69E4B5B111CECAE /* ManualTempBasalProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680C4420C9A345D46D90D06C /* ManualTempBasalProvider.swift */; };
 		C967DACD3B1E638F8B43BE06 /* ManualTempBasalStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFCFE0781F9074C2917890E8 /* ManualTempBasalStateModel.swift */; };
@@ -338,7 +329,6 @@
 		E0CC2C5C275B9F0F00A7BC71 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0CC2C5B275B9DAE00A7BC71 /* HealthKit.framework */; };
 		E0D4F80527513ECF00BDF1FE /* HealthKitSample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0D4F80427513ECF00BDF1FE /* HealthKitSample.swift */; };
 		E13B7DAB2A435F57066AF02E /* TargetsEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36F58DDD71F0E795464FA3F0 /* TargetsEditorStateModel.swift */; };
-		E25073BC86C11C3D6A42F5AC /* CalibrationsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47DFCE895C930F784EF11843 /* CalibrationsStateModel.swift */; };
 		E39E418C56A5A46B61D960EE /* ConfigEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D5B4F8B4194BB7E260EF251 /* ConfigEditorStateModel.swift */; };
 		E3A08AAE59538BC8A8ABE477 /* NotificationsConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3260468377DA9DB4DEE9AF6D /* NotificationsConfigDataFlow.swift */; };
 		E4984C5262A90469788754BB /* PreferencesEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8BA8533F56BC55748CA877 /* PreferencesEditorProvider.swift */; };
@@ -510,7 +500,6 @@
 		19F95FF629F10FEE00314DDC /* StatStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatStateModel.swift; sourceTree = "<group>"; };
 		19F95FF929F1102A00314DDC /* StatRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatRootView.swift; sourceTree = "<group>"; };
 		1CAE81192B118804DCD23034 /* SnoozeProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SnoozeProvider.swift; sourceTree = "<group>"; };
-		212E8BFE6D66EE65AA26A114 /* CalibrationsProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CalibrationsProvider.swift; sourceTree = "<group>"; };
 		223EC0494F55A91E3EA69EF4 /* BolusStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BolusStateModel.swift; sourceTree = "<group>"; };
 		22963BD06A9C83959D4914E4 /* NotificationsConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigRootView.swift; sourceTree = "<group>"; };
 		2AD22C985B79A2F0D2EA3D9D /* PumpConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpConfigRootView.swift; sourceTree = "<group>"; };
@@ -588,8 +577,6 @@
 		385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutStatus.swift; sourceTree = "<group>"; };
 		385CEAC025F2EA52002D6D5B /* Announcement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Announcement.swift; sourceTree = "<group>"; };
 		385CEAC325F2F154002D6D5B /* AnnouncementsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementsStorage.swift; sourceTree = "<group>"; };
-		3862CC04273D152B00BF832C /* CalibrationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalibrationService.swift; sourceTree = "<group>"; };
-		3862CC1E273FDC9200BF832C /* CalibrationsChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalibrationsChart.swift; sourceTree = "<group>"; };
 		3862CC2D2743F9F700BF832C /* CalendarManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarManager.swift; sourceTree = "<group>"; };
 		386A124E271707F000DDC61C /* DexcomSourceG6.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomSourceG6.swift; sourceTree = "<group>"; };
 		3870FF4225EC13F40088248F /* BloodGlucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloodGlucose.swift; sourceTree = "<group>"; };
@@ -718,9 +705,7 @@
 		3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConfigEditorDataFlow.swift; sourceTree = "<group>"; };
 		42369F66CF91F30624C0B3A6 /* BasalProfileEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorProvider.swift; sourceTree = "<group>"; };
 		44080E4709E3AE4B73054563 /* ConfigEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConfigEditorProvider.swift; sourceTree = "<group>"; };
-		47DFCE895C930F784EF11843 /* CalibrationsStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CalibrationsStateModel.swift; sourceTree = "<group>"; };
 		4DD795BA46B193644D48138C /* TargetsEditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorRootView.swift; sourceTree = "<group>"; };
-		500371C09F54F89A97D65FDB /* CalibrationsRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CalibrationsRootView.swift; sourceTree = "<group>"; };
 		505E09DC17A0C3D0AF4B66FE /* ISFEditorStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ISFEditorStateModel.swift; sourceTree = "<group>"; };
 		5B8A42073A2D03A278914448 /* AddTempTargetDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddTempTargetDataFlow.swift; sourceTree = "<group>"; };
 		5C018D1680307A31C9ED7120 /* CGMStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CGMStateModel.swift; sourceTree = "<group>"; };
@@ -729,7 +714,6 @@
 		60744C3E9BB3652895C908CC /* DataTableProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableProvider.swift; sourceTree = "<group>"; };
 		618E62C9757B2F95431B5DC0 /* AddCarbsProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddCarbsProvider.swift; sourceTree = "<group>"; };
 		64AA5E04A2761F6EEA6568E1 /* CREditorStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CREditorStateModel.swift; sourceTree = "<group>"; };
-		66A5B83E7967C38F7CBD883C /* LibreConfigDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LibreConfigDataFlow.swift; sourceTree = "<group>"; };
 		67F94DD2853CF42BA4E30616 /* BasalProfileEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorDataFlow.swift; sourceTree = "<group>"; };
 		680C4420C9A345D46D90D06C /* ManualTempBasalProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalProvider.swift; sourceTree = "<group>"; };
 		6F8BA8533F56BC55748CA877 /* PreferencesEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PreferencesEditorProvider.swift; sourceTree = "<group>"; };
@@ -760,7 +744,6 @@
 		B9B5C0607505A38F256BF99A /* CGMDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CGMDataFlow.swift; sourceTree = "<group>"; };
 		B9CAAEFB2AE70836000F68BC /* branch.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = branch.txt; sourceTree = SOURCE_ROOT; };
 		BA49538D56989D8DA6FCF538 /* TargetsEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorDataFlow.swift; sourceTree = "<group>"; };
-		BC210C0F3CB6D3C86E5DED4E /* LibreConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LibreConfigRootView.swift; sourceTree = "<group>"; };
 		BF8BCB0C37DEB5EC377B9612 /* BasalProfileEditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorRootView.swift; sourceTree = "<group>"; };
 		C19984D62EFC0035A9E9644D /* BolusProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BolusProvider.swift; sourceTree = "<group>"; };
 		C377490C77661D75E8C50649 /* ManualTempBasalRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalRootView.swift; sourceTree = "<group>"; };
@@ -798,6 +781,8 @@
 		CE94598129E9E3D30047C9C6 /* WatchConfigProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConfigProvider.swift; sourceTree = "<group>"; };
 		CE94598329E9E3E60047C9C6 /* WatchConfigStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConfigStateModel.swift; sourceTree = "<group>"; };
 		CE94598629E9E4110047C9C6 /* WatchConfigRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConfigRootView.swift; sourceTree = "<group>"; };
+		CE95BF492BA5CED700DC3DE3 /* LoopKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		CE95BF4A2BA5CED700DC3DE3 /* LoopKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		CEA4F62229BE10F70011ADF7 /* SavitzkyGolayFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavitzkyGolayFilter.swift; sourceTree = "<group>"; };
 		CEB434DB28B8F5B900B70274 /* MKRingProgressView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MKRingProgressView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		CEB434DE28B8F5C400B70274 /* OmniBLE.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OmniBLE.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -813,7 +798,6 @@
 		D0BDC6993C1087310EDFC428 /* CREditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CREditorRootView.swift; sourceTree = "<group>"; };
 		D295A3F870E826BE371C0BB5 /* AutotuneConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AutotuneConfigStateModel.swift; sourceTree = "<group>"; };
 		D97F14812C1AFED3621165A5 /* PumpSettingsEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpSettingsEditorProvider.swift; sourceTree = "<group>"; };
-		DA241FB1663EC96FDBE64C8A /* CalibrationsDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CalibrationsDataFlow.swift; sourceTree = "<group>"; };
 		DC2C6489D29ECCCAD78E0721 /* NotificationsConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigStateModel.swift; sourceTree = "<group>"; };
 		E00EEBFD27368630002FF094 /* ServiceAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceAssembly.swift; sourceTree = "<group>"; };
 		E00EEBFE27368630002FF094 /* SecurityAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecurityAssembly.swift; sourceTree = "<group>"; };
@@ -826,9 +810,7 @@
 		E0CC2C5B275B9DAE00A7BC71 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
 		E0D4F80427513ECF00BDF1FE /* HealthKitSample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitSample.swift; sourceTree = "<group>"; };
 		E26904AACA8D9C15D229D675 /* SnoozeStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SnoozeStateModel.swift; sourceTree = "<group>"; };
-		E2EBA7C03C26FCC67E16D798 /* LibreConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LibreConfigProvider.swift; sourceTree = "<group>"; };
 		E625985B47742D498CB1681A /* NotificationsConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigProvider.swift; sourceTree = "<group>"; };
-		E68CDC1E5C438D1BEAD4CF24 /* LibreConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LibreConfigStateModel.swift; sourceTree = "<group>"; };
 		E9AAB83FB6C3B41EFD1846A0 /* AddTempTargetRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddTempTargetRootView.swift; sourceTree = "<group>"; };
 		F816825D28DB441200054060 /* HeartBeatManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeartBeatManager.swift; sourceTree = "<group>"; };
 		F816825F28DB441800054060 /* BluetoothTransmitter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothTransmitter.swift; sourceTree = "<group>"; };
@@ -1086,14 +1068,12 @@
 				A42F1FEDFFD0DDE00AAD54D3 /* BasalProfileEditor */,
 				3811DE0425C9D32E00A708ED /* Base */,
 				C2C98283C436DB934D7E7994 /* Bolus */,
-				E8176B120B55CE89F1591542 /* Calibrations */,
 				F75CB57ED6971B46F8756083 /* CGM */,
 				0610F7D6D2EC00E3BA1569F0 /* ConfigEditor */,
 				E42231DBF0DBE2B4B92D1B15 /* CREditor */,
 				9E56E3626FAD933385101B76 /* DataTable */,
 				3811DE2725C9D49500A708ED /* Home */,
 				D8F047E14D567F2B5DBEFD96 /* ISFEditor */,
-				C11D545CED3ECEB525EDEE23 /* LibreConfig */,
 				3811DE1A25C9D48300A708ED /* Main */,
 				5031FE61F63C2A8A8B7674DD /* ManualTempBasal */,
 				D533BF261CDC1C3F871E7BFD /* NightscoutConfig */,
@@ -1347,6 +1327,8 @@
 		3818AA48274C267000843DB3 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				CE95BF492BA5CED700DC3DE3 /* LoopKit.framework */,
+				CE95BF4A2BA5CED700DC3DE3 /* LoopKitUI.framework */,
 				CE51DD1B2A01970800F163F7 /* ConnectIQ 2.xcframework */,
 				CE94597929E9DF7B0047C9C6 /* ConnectIQ.framework */,
 				CEC751D529D88262006E9D24 /* MinimedKit.framework */,
@@ -1412,20 +1394,11 @@
 				38569345270B5DFA0002C50D /* GlucoseSource.swift */,
 				E013D871273AC6FE0014109C /* GlucoseSimulatorSource.swift */,
 				38FEF407273B011A00574A46 /* LibreTransmitterSource.swift */,
-				3862CC03273D150600BF832C /* Calibrations */,
 				CECA4774298DA8310095139F /* DexcomSourceG5.swift */,
 			);
 			path = CGM;
 			sourceTree = "<group>";
 		};
-		3862CC03273D150600BF832C /* Calibrations */ = {
-			isa = PBXGroup;
-			children = (
-				3862CC04273D152B00BF832C /* CalibrationService.swift */,
-			);
-			path = Calibrations;
-			sourceTree = "<group>";
-		};
 		3862CC2C2743F9DC00BF832C /* Calendar */ = {
 			isa = PBXGroup;
 			children = (
@@ -1776,15 +1749,6 @@
 			path = View;
 			sourceTree = "<group>";
 		};
-		43952E72FE7AF85715FE020E /* View */ = {
-			isa = PBXGroup;
-			children = (
-				500371C09F54F89A97D65FDB /* CalibrationsRootView.swift */,
-				3862CC1E273FDC9200BF832C /* CalibrationsChart.swift */,
-			);
-			path = View;
-			sourceTree = "<group>";
-		};
 		4E8C7B59F8065047ECE20965 /* View */ = {
 			isa = PBXGroup;
 			children = (
@@ -1936,14 +1900,6 @@
 			path = BasalProfileEditor;
 			sourceTree = "<group>";
 		};
-		A56097CB1DCBCE98F2F42177 /* View */ = {
-			isa = PBXGroup;
-			children = (
-				BC210C0F3CB6D3C86E5DED4E /* LibreConfigRootView.swift */,
-			);
-			path = View;
-			sourceTree = "<group>";
-		};
 		A9A4C88374496B3C89058A89 /* AddTempTarget */ = {
 			isa = PBXGroup;
 			children = (
@@ -1963,17 +1919,6 @@
 			path = View;
 			sourceTree = "<group>";
 		};
-		C11D545CED3ECEB525EDEE23 /* LibreConfig */ = {
-			isa = PBXGroup;
-			children = (
-				66A5B83E7967C38F7CBD883C /* LibreConfigDataFlow.swift */,
-				E2EBA7C03C26FCC67E16D798 /* LibreConfigProvider.swift */,
-				E68CDC1E5C438D1BEAD4CF24 /* LibreConfigStateModel.swift */,
-				A56097CB1DCBCE98F2F42177 /* View */,
-			);
-			path = LibreConfig;
-			sourceTree = "<group>";
-		};
 		C2C98283C436DB934D7E7994 /* Bolus */ = {
 			isa = PBXGroup;
 			children = (
@@ -2102,17 +2047,6 @@
 			path = PumpSettingsEditor;
 			sourceTree = "<group>";
 		};
-		E8176B120B55CE89F1591542 /* Calibrations */ = {
-			isa = PBXGroup;
-			children = (
-				DA241FB1663EC96FDBE64C8A /* CalibrationsDataFlow.swift */,
-				212E8BFE6D66EE65AA26A114 /* CalibrationsProvider.swift */,
-				47DFCE895C930F784EF11843 /* CalibrationsStateModel.swift */,
-				43952E72FE7AF85715FE020E /* View */,
-			);
-			path = Calibrations;
-			sourceTree = "<group>";
-		};
 		EEC747824D6593B5CD87E195 /* View */ = {
 			isa = PBXGroup;
 			children = (
@@ -2560,7 +2494,6 @@
 				CE82E02528E867BA00473A9C /* AlertStorage.swift in Sources */,
 				38BF021D25E7E3AF00579895 /* Reservoir.swift in Sources */,
 				38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */,
-				3862CC05273D152B00BF832C /* CalibrationService.swift in Sources */,
 				3811DEEA25CA063400A708ED /* SyncAccess.swift in Sources */,
 				190EBCC829FF13AA00BA767D /* StatConfigStateModel.swift in Sources */,
 				38BF021F25E7F0DE00579895 /* DeviceDataManager.swift in Sources */,
@@ -2694,7 +2627,6 @@
 				19D4E4EB29FC6A9F00351451 /* TIRforChart.swift in Sources */,
 				FEFFA7A22929FE49007B8193 /* UIDevice+Extensions.swift in Sources */,
 				F90692D3274B9A130037068D /* AppleHealthKitRootView.swift in Sources */,
-				3862CC1F273FDC9200BF832C /* CalibrationsChart.swift in Sources */,
 				19E1F7EC29D082FE005C8D20 /* IconConfigStateModel.swift in Sources */,
 				711C0CB42CAABE788916BC9D /* ManualTempBasalDataFlow.swift in Sources */,
 				BF1667ADE69E4B5B111CECAE /* ManualTempBasalProvider.swift in Sources */,
@@ -2717,16 +2649,8 @@
 				38569349270B5DFB0002C50D /* AppGroupSource.swift in Sources */,
 				F5CA3DB1F9DC8B05792BBFAA /* CGMDataFlow.swift in Sources */,
 				BA00D96F7B2FF169A06FB530 /* CGMStateModel.swift in Sources */,
-				61962FCAF8A2D222553AC5A3 /* LibreConfigDataFlow.swift in Sources */,
-				6EADD581738D64431902AC0A /* LibreConfigProvider.swift in Sources */,
 				CE94598729E9E4110047C9C6 /* WatchConfigRootView.swift in Sources */,
-				903D18976088B09110BCBE29 /* LibreConfigStateModel.swift in Sources */,
-				9050F378F0063C064D7FFC86 /* LibreConfigRootView.swift in Sources */,
-				B7C465E9472624D8A2BE2A6A /* CalibrationsDataFlow.swift in Sources */,
-				320D030F724170A637F06D50 /* CalibrationsProvider.swift in Sources */,
 				19E1F7E829D082D0005C8D20 /* IconConfigDataFlow.swift in Sources */,
-				E25073BC86C11C3D6A42F5AC /* CalibrationsStateModel.swift in Sources */,
-				BA90041DC8991147E5C8C3AA /* CalibrationsRootView.swift in Sources */,
 				E3A08AAE59538BC8A8ABE477 /* NotificationsConfigDataFlow.swift in Sources */,
 				0F7A65FBD2CD8D6477ED4539 /* NotificationsConfigProvider.swift in Sources */,
 				3171D2818C7C72CD1584BB5E /* NotificationsConfigStateModel.swift in Sources */,

+ 211 - 1
FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme

@@ -3,7 +3,7 @@
    LastUpgradeVersion = "1240"
    version = "1.3">
    <BuildAction
-      parallelizeBuildables = "YES"
+      parallelizeBuildables = "NO"
       buildImplicitDependencies = "YES">
       <BuildActionEntries>
          <BuildActionEntry
@@ -14,6 +14,216 @@
             buildForAnalyzing = "YES">
             <BuildableReference
                BuildableIdentifier = "primary"
+               BlueprintIdentifier = "43D8FDCA1C728FDF0073BE78"
+               BuildableName = "LoopKit.framework"
+               BlueprintName = "LoopKit"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "A9E6758022713F4700E25293"
+               BuildableName = "LoopKit.framework"
+               BlueprintName = "LoopKit-watchOS"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "43BA7153201E484D0058961E"
+               BuildableName = "LoopKitUI.framework"
+               BlueprintName = "LoopKitUI"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "892A5D33222F03CB008961AB"
+               BuildableName = "LoopTestingKit.framework"
+               BlueprintName = "LoopTestingKit"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "89D2047121CC7BD7001238CC"
+               BuildableName = "MockKit.framework"
+               BlueprintName = "MockKit"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "89D2048E21CC7C12001238CC"
+               BuildableName = "MockKitUI.framework"
+               BlueprintName = "MockKitUI"
+               ReferencedContainer = "container:LoopKit/LoopKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C1E34B5A29C7AD01009A50A5"
+               BuildableName = "MinimedKitPlugin.loopplugin"
+               BlueprintName = "MinimedKitPlugin"
+               ReferencedContainer = "container:MinimedKit/MinimedKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C124021629C7D93D00B32844"
+               BuildableName = "OmniKitPlugin.loopplugin"
+               BlueprintName = "OmniKitPlugin"
+               ReferencedContainer = "container:OmniKit/OmniKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "B4D40D3D23A428BC00D7ECB5"
+               BuildableName = "CGMBLEKitG5Plugin.loopplugin"
+               BlueprintName = "CGMBLEKitG5Plugin"
+               ReferencedContainer = "container:CGMBLEKit/CGMBLEKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "B4D40D2D23A3E91800D7ECB5"
+               BuildableName = "CGMBLEKitG6Plugin.loopplugin"
+               BlueprintName = "CGMBLEKitG6Plugin"
+               ReferencedContainer = "container:CGMBLEKit/CGMBLEKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "B40BF25D23ABD47400A43CEE"
+               BuildableName = "ShareClientPlugin.loopplugin"
+               BlueprintName = "ShareClientPlugin"
+               ReferencedContainer = "container:dexcom-share-client-swift/ShareClient.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C17F511C291EACCD00555EB5"
+               BuildableName = "G7SensorPlugin.loopplugin"
+               BlueprintName = "G7SensorPlugin"
+               ReferencedContainer = "container:G7SensorKit/G7SensorKit.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C1BDBAE72A4397E200A787D1"
+               BuildableName = "LibreDemoPlugin.loopplugin"
+               BlueprintName = "LibreDemoPlugin"
+               ReferencedContainer = "container:LibreTransmitter/LibreTransmitter.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "B40BF25D23ABD47400A43CEE"
+               BuildableName = "LibreTransmitterPlugin.loopplugin"
+               BlueprintName = "LibreTransmitterPlugin"
+               ReferencedContainer = "container:LibreTransmitter/LibreTransmitter.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C187C196279086A8006E3557"
+               BuildableName = "OmniBLEPlugin.loopplugin"
+               BlueprintName = "OmniBLEPlugin"
+               ReferencedContainer = "container:OmniBLE/OmniBLE.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
                BlueprintIdentifier = "388E595725AD948C0019842D"
                BuildableName = "FreeAPS.app"
                BlueprintName = "FreeAPS"

+ 27 - 0
FreeAPS.xcworkspace/contents.xcworkspacedata

@@ -4,4 +4,31 @@
    <FileRef
       location = "group:FreeAPS.xcodeproj">
    </FileRef>
+   <FileRef
+      location = "group:MinimedKit/MinimedKit.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:LibreTransmitter/LibreTransmitter.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:OmniBLE/OmniBLE.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:RileyLinkKit/RileyLinkKit.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:CGMBLEKit/CGMBLEKit.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:dexcom-share-client-swift/ShareClient.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:LoopKit/LoopKit.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:OmniKit/OmniKit.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:G7SensorKit/G7SensorKit.xcodeproj">
+   </FileRef>
 </Workspace>

+ 83 - 67
FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -1,70 +1,86 @@
 {
-  "object": {
-    "pins": [
-      {
-        "package": "MKRingProgressView",
-        "repositoryURL": "https://github.com/maxkonovalov/MKRingProgressView.git",
-        "state": {
-          "branch": "master",
-          "revision": "660888aab1d2ab0ed7eb9eb53caec12af4955fa7",
-          "version": null
-        }
-      },
-      {
-        "package": "swift-algorithms",
-        "repositoryURL": "https://github.com/apple/swift-algorithms",
-        "state": {
-          "branch": null,
-          "revision": "2327673b0e9c7e90e6b1826376526ec3627210e4",
-          "version": "0.2.1"
-        }
-      },
-      {
-        "package": "swift-numerics",
-        "repositoryURL": "https://github.com/apple/swift-numerics",
-        "state": {
-          "branch": null,
-          "revision": "6583ac70c326c3ee080c1d42d9ca3361dca816cd",
-          "version": "0.1.0"
-        }
-      },
-      {
-        "package": "SwiftCharts",
-        "repositoryURL": "https://github.com/ivanschuetz/SwiftCharts.git",
-        "state": {
-          "branch": "master",
-          "revision": "c354c1945bb35a1f01b665b22474f6db28cba4a2",
-          "version": null
-        }
-      },
-      {
-        "package": "SwiftDate",
-        "repositoryURL": "https://github.com/malcommac/SwiftDate",
-        "state": {
-          "branch": null,
-          "revision": "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
-          "version": "6.3.1"
-        }
-      },
-      {
-        "package": "SwiftMessages",
-        "repositoryURL": "https://github.com/SwiftKickMobile/SwiftMessages",
-        "state": {
-          "branch": null,
-          "revision": "b29dd21090b708aa0ae9ecbaf6e2d0487028dc3f",
-          "version": "9.0.6"
-        }
-      },
-      {
-        "package": "Swinject",
-        "repositoryURL": "https://github.com/Swinject/Swinject",
-        "state": {
-          "branch": null,
-          "revision": "8bc503e60965298984fb58cf47b71c541449fe2a",
-          "version": "2.8.3"
-        }
+  "pins" : [
+    {
+      "identity" : "cryptoswift",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/krzyzanowskim/CryptoSwift",
+      "state" : {
+        "revision" : "19b3c3ceed117c5cc883517c4e658548315ba70b",
+        "version" : "1.6.0"
       }
-    ]
-  },
-  "version": 1
+    },
+    {
+      "identity" : "mkringprogressview",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/maxkonovalov/MKRingProgressView.git",
+      "state" : {
+        "branch" : "master",
+        "revision" : "660888aab1d2ab0ed7eb9eb53caec12af4955fa7"
+      }
+    },
+    {
+      "identity" : "slidebutton",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/no-comment/SlideButton",
+      "state" : {
+        "branch" : "main",
+        "revision" : "5eacebba4d7deeb693592bc9a62ab2d2181e133b"
+      }
+    },
+    {
+      "identity" : "swift-algorithms",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-algorithms",
+      "state" : {
+        "revision" : "2327673b0e9c7e90e6b1826376526ec3627210e4",
+        "version" : "0.2.1"
+      }
+    },
+    {
+      "identity" : "swift-numerics",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-numerics",
+      "state" : {
+        "revision" : "6583ac70c326c3ee080c1d42d9ca3361dca816cd",
+        "version" : "0.1.0"
+      }
+    },
+    {
+      "identity" : "swiftcharts",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/ivanschuetz/SwiftCharts.git",
+      "state" : {
+        "branch" : "master",
+        "revision" : "c354c1945bb35a1f01b665b22474f6db28cba4a2"
+      }
+    },
+    {
+      "identity" : "swiftdate",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/malcommac/SwiftDate",
+      "state" : {
+        "revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
+        "version" : "6.3.1"
+      }
+    },
+    {
+      "identity" : "swiftmessages",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/SwiftKickMobile/SwiftMessages",
+      "state" : {
+        "revision" : "b29dd21090b708aa0ae9ecbaf6e2d0487028dc3f",
+        "version" : "9.0.6"
+      }
+    },
+    {
+      "identity" : "swinject",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/Swinject/Swinject",
+      "state" : {
+        "revision" : "8bc503e60965298984fb58cf47b71c541449fe2a",
+        "version" : "2.8.3"
+      }
+    }
+  ],
+  "version" : 2
 }

+ 22 - 1
FreeAPS/Sources/APS/CGM/AppGroupSource.swift

@@ -1,8 +1,29 @@
 import Combine
 import Foundation
-import LibreTransmitter
+import LoopKit
 import LoopKitUI
 
+public extension GlucoseTrend {
+    var direction: String {
+        switch self {
+        case .upUpUp:
+            return "DoubleUp"
+        case .upUp:
+            return "SingleUp"
+        case .up:
+            return "FortyFiveUp"
+        case .flat:
+            return "Flat"
+        case .down:
+            return "FortyFiveDown"
+        case .downDown:
+            return "SingleDown"
+        case .downDownDown:
+            return "DoubleDown"
+        }
+    }
+}
+
 struct AppGroupSource: GlucoseSource {
     var cgmManager: CGMManagerUI?
     var glucoseManager: FetchGlucoseManager?

+ 0 - 119
FreeAPS/Sources/APS/CGM/Calibrations/CalibrationService.swift

@@ -1,119 +0,0 @@
-import Foundation
-import LibreTransmitter
-import Swinject
-
-struct Calibration: JSON, Hashable, Identifiable {
-    let x: Double
-    let y: Double
-    var date = Date()
-
-    static let zero = Calibration(x: 0, y: 0)
-
-    var id = UUID()
-}
-
-protocol CalibrationService {
-    var slope: Double { get }
-    var intercept: Double { get }
-    var calibrations: [Calibration] { get }
-
-    func addCalibration(_ calibration: Calibration)
-    func removeCalibration(_ calibration: Calibration)
-    func removeAllCalibrations()
-    func removeLast()
-
-    func calibrate(value: Double) -> Double
-}
-
-final class BaseCalibrationService: CalibrationService, Injectable {
-    private enum Config {
-        static let minSlope = 0.8
-        static let maxSlope = 1.25
-        static let minIntercept = -100.0
-        static let maxIntercept = 100.0
-        static let maxValue = 500.0
-        static let minValue = 0.0
-    }
-
-    @Injected() var storage: FileStorage!
-    @Injected() var notificationCenter: NotificationCenter!
-    private var lifetime = Lifetime()
-
-    private(set) var calibrations: [Calibration] = [] {
-        didSet {
-            storage.save(calibrations, as: OpenAPS.FreeAPS.calibrations)
-        }
-    }
-
-    init(resolver: Resolver) {
-        injectServices(resolver)
-        calibrations = storage.retrieve(OpenAPS.FreeAPS.calibrations, as: [Calibration].self) ?? []
-        subscribe()
-    }
-
-    private func subscribe() {
-        notificationCenter.publisher(for: .newSensorDetected)
-            .sink { [weak self] _ in
-                self?.removeAllCalibrations()
-            }
-            .store(in: &lifetime)
-    }
-
-    var slope: Double {
-        guard calibrations.count >= 2 else {
-            return 1
-        }
-
-        let xs = calibrations.map(\.x)
-        let ys = calibrations.map(\.y)
-        let sum1 = average(multiply(xs, ys)) - average(xs) * average(ys)
-        let sum2 = average(multiply(xs, xs)) - pow(average(xs), 2)
-        let slope = sum1 / sum2
-
-        return min(max(slope, Config.minSlope), Config.maxSlope)
-    }
-
-    var intercept: Double {
-        guard calibrations.count >= 1 else {
-            return 0
-        }
-        let xs = calibrations.map(\.x)
-        let ys = calibrations.map(\.y)
-
-        let intercept = average(ys) - slope * average(xs)
-
-        return min(max(intercept, Config.minIntercept), Config.maxIntercept)
-    }
-
-    func calibrate(value: Double) -> Double {
-        linearRegression(value)
-    }
-
-    func addCalibration(_ calibration: Calibration) {
-        calibrations.append(calibration)
-    }
-
-    func removeCalibration(_ calibration: Calibration) {
-        calibrations.removeAll { $0 == calibration }
-    }
-
-    func removeAllCalibrations() {
-        calibrations.removeAll()
-    }
-
-    func removeLast() {
-        calibrations.removeLast()
-    }
-
-    private func average(_ input: [Double]) -> Double {
-        input.reduce(0, +) / Double(input.count)
-    }
-
-    private func multiply(_ a: [Double], _ b: [Double]) -> [Double] {
-        zip(a, b).map(*)
-    }
-
-    private func linearRegression(_ x: Double) -> Double {
-        (intercept + slope * x).clamped(Config.minValue ... Config.maxValue)
-    }
-}

+ 144 - 61
FreeAPS/Sources/APS/CGM/LibreTransmitterSource.swift

@@ -1,41 +1,38 @@
 import Combine
 import Foundation
 import LibreTransmitter
+import LibreTransmitterUI
+import LoopKit
 import LoopKitUI
 import Swinject
 
-protocol LibreTransmitterSource: GlucoseSource {
-    var manager: LibreTransmitterManager? { get set }
-}
+// protocol LibreTransmitterSource: GlucoseSource {
+//    var manager: LibreTransmitterManager? { get set }
+// }
+
+final class LibreTransmitterSource: GlucoseSource {
+    private let processQueue = DispatchQueue(label: "BaseLibreTransmitterSource.processQueue")
+    private var glucoseStorage: GlucoseStorage!
+    var glucoseManager: FetchGlucoseManager?
 
-final class BaseLibreTransmitterSource: LibreTransmitterSource, Injectable {
     var cgmManager: CGMManagerUI?
     var cgmType: CGMType = .libreTransmitter
 
-    private let processQueue = DispatchQueue(label: "BaseLibreTransmitterSource.processQueue")
+    var cgmHasValidSensorSession: Bool = false
 
-    @Injected() var glucoseStorage: GlucoseStorage!
-    @Injected() var calibrationService: CalibrationService!
+    // @Injected() var glucoseStorage: GlucoseStorage!
+//    @Injected() var calibrationService: CalibrationService!
 
     private var promise: Future<[BloodGlucose], Error>.Promise?
 
-    var glucoseManager: FetchGlucoseManager?
+//    @Persisted(key: "LibreTransmitterManager.configured") private(set) var configured = false
 
-    var manager: LibreTransmitterManager? {
-        didSet {
-            configured = manager != nil
-            manager?.cgmManagerDelegate = self
-        }
-    }
-
-    @Persisted(key: "LibreTransmitterManager.configured") private(set) var configured = false
-
-    init(resolver: Resolver) {
-        if configured {
-            manager = LibreTransmitterManager()
-            manager?.cgmManagerDelegate = self
-        }
-        injectServices(resolver)
+    init(glucoseStorage: GlucoseStorage, glucoseManager: FetchGlucoseManager) {
+        self.glucoseStorage = glucoseStorage
+        self.glucoseManager = glucoseManager
+        cgmManager = LibreTransmitterManagerV3()
+        cgmManager?.cgmManagerDelegate = self
+        cgmManager?.delegateQueue = processQueue
     }
 
     func fetch(_: DispatchTimer?) -> AnyPublisher<[BloodGlucose], Never> {
@@ -49,55 +46,141 @@ final class BaseLibreTransmitterSource: LibreTransmitterSource, Injectable {
     }
 
     func fetchIfNeeded() -> AnyPublisher<[BloodGlucose], Never> {
-        fetch(nil)
+        Future<[BloodGlucose], Error> { _ in
+            self.processQueue.async {
+                guard let cgmManager = self.cgmManager else { return }
+                cgmManager.fetchNewDataIfNeeded { result in
+                    self.processCGMReadingResult(cgmManager, readingResult: result) {
+                        // nothing to do
+                    }
+                }
+            }
+        }
+        .timeout(60, scheduler: processQueue, options: nil, customError: nil)
+        .replaceError(with: [])
+        .replaceEmpty(with: [])
+        .eraseToAnyPublisher()
     }
 
-    func sourceInfo() -> [String: Any]? {
-        if let battery = manager?.battery {
-            return ["transmitterBattery": battery]
+//    func sourceInfo() -> [String: Any]? {
+//        if let battery = manager?.battery {
+//            return ["transmitterBattery": battery]
+//        }
+//        return nil
+//    }
+}
+
+extension LibreTransmitterSource: CGMManagerDelegate {
+    private func processCGMReadingResult(
+        _: CGMManager,
+        readingResult: CGMReadingResult,
+        completion: @escaping () -> Void
+    ) {
+        switch readingResult {
+        case let .newData(values):
+            if let libreManager = cgmManager as? LibreTransmitterManagerV3 {
+                let glucose = values.compactMap { newGlucoseSample -> BloodGlucose in
+                    let quantity = newGlucoseSample.quantity
+                    let value = Int(quantity.doubleValue(for: .milligramsPerDeciliter))
+                    return BloodGlucose(
+                        _id: UUID().uuidString,
+                        sgv: value,
+                        direction: .init(trendType: newGlucoseSample.trend),
+                        date: Decimal(Int(newGlucoseSample.date.timeIntervalSince1970 * 1000)),
+                        dateString: newGlucoseSample.date,
+                        unfiltered: Decimal(value),
+                        filtered: nil,
+                        noise: nil,
+                        glucose: value,
+                        type: "sgv",
+                        activationDate: libreManager.sensorInfoObservable.activatedAt,
+                        sessionStartDate: libreManager.sensorInfoObservable.activatedAt,
+                        transmitterID: libreManager.sensorInfoObservable.sensorSerial
+                    )
+                }
+                NSLog("Debug Libre \(glucose)")
+                promise?(.success(glucose))
+                completion()
+            }
+
+        case .unreliableData:
+            promise?(.failure(GlucoseDataError.unreliableData))
+            completion()
+        case .noData:
+            promise?(.failure(GlucoseDataError.noData))
+            completion()
+        case let .error(error):
+            promise?(.failure(error))
+            completion()
         }
-        return nil
     }
-}
 
-extension BaseLibreTransmitterSource: LibreTransmitterManagerDelegate {
-    var queue: DispatchQueue { processQueue }
+    func cgmManager(_ manager: LoopKit.CGMManager, hasNew readingResult: LoopKit.CGMReadingResult) {
+        dispatchPrecondition(condition: .onQueue(processQueue))
+        processCGMReadingResult(manager, readingResult: readingResult) {
+            debug(.deviceManager, "Libre transmitter - Direct return done")
+        }
+    }
 
-    func startDateToFilterNewData(for _: LibreTransmitterManager) -> Date? {
-        glucoseStorage.syncDate()
+    func cgmManagerDidUpdateState(_: LoopKit.CGMManager) {
+        // TODO: if useful in regard of configuration
     }
 
-    func cgmManager(_ manager: LibreTransmitterManager, hasNew result: Result<[LibreGlucose], Error>) {
-        switch result {
-        case let .success(newGlucose):
-            let glucose = newGlucose.map { value -> BloodGlucose in
-                BloodGlucose(
-                    _id: UUID().uuidString,
-                    sgv: Int(value.glucose),
-                    direction: manager.glucoseDisplay?.trendType
-                        .map { .init(trendType: $0) },
-                    date: Decimal(Int(value.startDate.timeIntervalSince1970 * 1000)),
-                    dateString: value.startDate,
-                    unfiltered: Decimal(value.unsmoothedGlucose),
-                    filtered: nil,
-                    noise: nil,
-                    glucose: Int(value.glucose),
-                    type: "sgv",
-                    activationDate: value.sensorStartDate ?? manager.sensorStartDate,
-                    sessionStartDate: value.sensorStartDate ?? manager.sensorStartDate,
-                    transmitterID: manager.sensorSerialNumber
-                )
+    func cgmManager(_: LoopKit.CGMManager, didUpdate status: LoopKit.CGMManagerStatus) {
+        DispatchQueue.main.async {
+            if self.cgmHasValidSensorSession != status.hasValidSensorSession {
+                self.cgmHasValidSensorSession = status.hasValidSensorSession
             }
-            NSLog("Debug Libre \(glucose)")
-            promise?(.success(glucose))
-
-        case let .failure(error):
-            warning(.service, "LibreTransmitter error:", error: error)
-            promise?(.failure(error))
         }
     }
 
-    func overcalibration(for _: LibreTransmitterManager) -> ((Double) -> (Double))? {
-        calibrationService.calibrate
+    func startDateToFilterNewData(for _: LoopKit.CGMManager) -> Date? {
+        dispatchPrecondition(condition: .onQueue(processQueue))
+        return glucoseStorage.lastGlucoseDate()
     }
+
+    func cgmManager(_: LoopKit.CGMManager, hasNew events: [LoopKit.PersistedCgmEvent]) {
+        // TODO: Events in APS ?
+        // currently only display in log the date of the event
+        events.forEach { debug(.deviceManager, "events from CGM at \($0.date)") }
+    }
+
+    func cgmManagerWantsDeletion(_ manager: LoopKit.CGMManager) {
+        dispatchPrecondition(condition: .onQueue(processQueue))
+        debug(.deviceManager, " CGM Manager with identifier \(manager.pluginIdentifier) wants deletion")
+        glucoseManager?.cgmGlucoseSourceType = nil
+    }
+
+    func credentialStoragePrefix(for _: LoopKit.CGMManager) -> String {
+        UUID().uuidString
+    }
+
+    func deviceManager(
+        _: LoopKit.DeviceManager,
+        logEventForDeviceIdentifier deviceIdentifier: String?,
+        type _: LoopKit.DeviceLogEntryType,
+        message: String,
+        completion _: ((Error?) -> Void)?
+    ) {
+        debug(.deviceManager, "device Manager for \(String(describing: deviceIdentifier)) : \(message)")
+    }
+
+    func issueAlert(_: LoopKit.Alert) {}
+
+    func retractAlert(identifier _: LoopKit.Alert.Identifier) {}
+
+    func doesIssuedAlertExist(identifier _: LoopKit.Alert.Identifier, completion _: @escaping (Result<Bool, Error>) -> Void) {}
+
+    func lookupAllUnretracted(
+        managerIdentifier _: String,
+        completion _: @escaping (Result<[LoopKit.PersistedAlert], Error>) -> Void
+    ) {}
+
+    func lookupAllUnacknowledgedUnretracted(
+        managerIdentifier _: String,
+        completion _: @escaping (Result<[LoopKit.PersistedAlert], Error>) -> Void
+    ) {}
+
+    func recordRetractedAlert(_: LoopKit.Alert, at _: Date) {}
 }
+

+ 0 - 18
FreeAPS/Sources/APS/Extensions/BloodGlucoseExtensions.swift

@@ -48,22 +48,4 @@ extension BloodGlucose.Direction {
         }
     }
 
-    init(trendType: LibreTransmitter.GlucoseTrend) {
-        switch trendType {
-        case .upUpUp:
-            self = .doubleUp
-        case .upUp:
-            self = .singleUp
-        case .up:
-            self = .fortyFiveUp
-        case .flat:
-            self = .flat
-        case .down:
-            self = .fortyFiveDown
-        case .downDown:
-            self = .singleDown
-        case .downDownDown:
-            self = .doubleDown
-        }
-    }
 }

+ 0 - 1
FreeAPS/Sources/Modules/CGM/CGMStateModel.swift

@@ -6,7 +6,6 @@ import SwiftUI
 
 extension CGM {
     final class StateModel: BaseStateModel<Provider> {
-        @Injected() var libreSource: LibreTransmitterSource!
         @Injected() var cgmManager: FetchGlucoseManager!
         @Injected() var calendarManager: CalendarManager!
 

+ 1 - 1
FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift

@@ -28,7 +28,7 @@ extension CGM {
                             }
                         }
                     }
-                    if [.dexcomG5, .dexcomG6, .dexcomG7].contains(state.cgm) {
+                    if [.dexcomG5, .dexcomG6, .dexcomG7, .libreTransmitter].contains(state.cgm) {
                         Section {
                             Button("CGM Configuration") {
                                 setupCGM.toggle()

+ 10 - 0
FreeAPS/Sources/Modules/CGM/View/CGMSetupView.swift

@@ -2,6 +2,8 @@ import CGMBLEKit
 import CGMBLEKitUI
 import G7SensorKit
 import G7SensorKitUI
+import LibreTransmitter
+import LibreTransmitterUI
 import LoopKit
 import LoopKitUI
 import SwiftUI
@@ -53,6 +55,14 @@ extension CGM {
                         allowDebugFeatures: false,
                         prefersToSkipUserInteraction: false
                     )
+            case .libreTransmitter:
+                setupViewController = LibreTransmitterManagerV3.setupViewController(
+                    bluetoothProvider: bluetoothManager,
+                    displayGlucosePreference: displayGlucosePreference,
+                    colorPalette: .default,
+                    allowDebugFeatures: false,
+                    prefersToSkipUserInteraction: false
+                )
             default:
                 break
             }

+ 0 - 13
FreeAPS/Sources/Modules/Calibrations/CalibrationsDataFlow.swift

@@ -1,13 +0,0 @@
-enum Calibrations {
-    enum Config {}
-
-    struct Item: Hashable, Identifiable {
-        let calibration: Calibration
-
-        var id: String {
-            calibration.id.uuidString
-        }
-    }
-}
-
-protocol CalibrationsProvider {}

+ 0 - 3
FreeAPS/Sources/Modules/Calibrations/CalibrationsProvider.swift

@@ -1,3 +0,0 @@
-extension Calibrations {
-    final class Provider: BaseProvider, CalibrationsProvider {}
-}

+ 0 - 73
FreeAPS/Sources/Modules/Calibrations/CalibrationsStateModel.swift

@@ -1,73 +0,0 @@
-import SwiftDate
-import SwiftUI
-
-extension Calibrations {
-    final class StateModel: BaseStateModel<Provider> {
-        @Injected() var glucoseStorage: GlucoseStorage!
-        @Injected() var calibrationService: CalibrationService!
-
-        @Published var slope: Double = 1
-        @Published var intercept: Double = 1
-        @Published var newCalibration: Decimal = 0
-        @Published var calibrations: [Calibration] = []
-        @Published var calibrate: (Double) -> Double = { $0 }
-        @Published var items: [Item] = []
-
-        var units: GlucoseUnits = .mmolL
-
-        override func subscribe() {
-            units = settingsManager.settings.units
-            calibrate = calibrationService.calibrate
-            setupCalibrations()
-        }
-
-        private func setupCalibrations() {
-            slope = calibrationService.slope
-            intercept = calibrationService.intercept
-            calibrations = calibrationService.calibrations
-            items = calibrations.map {
-                Item(calibration: $0)
-            }
-        }
-
-        func addCalibration() {
-            defer {
-                UIApplication.shared.endEditing()
-                setupCalibrations()
-            }
-
-            var glucose = newCalibration
-            if units == .mmolL {
-                glucose = newCalibration.asMgdL
-            }
-
-            guard let lastGlucose = glucoseStorage.recent().last,
-                  lastGlucose.dateString.addingTimeInterval(60 * 4.5) > Date(),
-                  let unfiltered = lastGlucose.unfiltered
-            else {
-                info(.service, "Glucose is stale for calibration")
-                return
-            }
-
-            let calibration = Calibration(x: Double(unfiltered), y: Double(glucose))
-
-            calibrationService.addCalibration(calibration)
-        }
-
-        func removeLast() {
-            calibrationService.removeLast()
-            setupCalibrations()
-        }
-
-        func removeAll() {
-            calibrationService.removeAllCalibrations()
-            setupCalibrations()
-        }
-
-        func removeAtIndex(_ index: Int) {
-            let calibration = calibrations[index]
-            calibrationService.removeCalibration(calibration)
-            setupCalibrations()
-        }
-    }
-}

+ 0 - 60
FreeAPS/Sources/Modules/Calibrations/View/CalibrationsChart.swift

@@ -1,60 +0,0 @@
-import SwiftUI
-
-struct CalibrationsChart: View {
-    @EnvironmentObject var state: Calibrations.StateModel
-
-    private var dateFormatter: DateFormatter {
-        let formatter = DateFormatter()
-        formatter.timeStyle = .short
-        formatter.dateStyle = .short
-        return formatter
-    }
-
-    private let maxValue = 400.0
-
-    var body: some View {
-        GeometryReader { geo in
-            ZStack(alignment: .top) {
-                Rectangle().fill(Color.secondary)
-                    .frame(height: geo.size.width)
-                Path { path in
-                    let size = geo.size.width
-                    path.move(
-                        to:
-                        CGPoint(
-                            x: 0,
-                            y: size - state.calibrate(0) / maxValue * geo.size.width
-                        )
-                    )
-                    path.addLine(
-                        to: CGPoint(
-                            x: size,
-                            y: size - state.calibrate(maxValue) / maxValue * geo.size.width
-                        )
-                    )
-                }
-                .stroke(.blue, lineWidth: 2)
-
-                ForEach(state.calibrations, id: \.self) { value in
-                    ZStack {
-                        Circle().fill(.red)
-                            .frame(width: 6, height: 6)
-                            .position(
-                                x: value.x / maxValue * geo.size.width,
-                                y: geo.size.width - (value.y / maxValue * geo.size.width)
-                            )
-                        Text(dateFormatter.string(from: value.date))
-                            .foregroundColor(.white)
-                            .font(.system(size: 10))
-                            .position(
-                                x: value.x / maxValue * geo.size.width,
-                                y: geo.size.width - (value.y / maxValue * geo.size.width) + 10
-                            )
-                    }
-                }
-            }
-            .frame(height: geo.size.width)
-            .clipped()
-        }
-    }
-}

+ 0 - 108
FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift

@@ -1,108 +0,0 @@
-import SwiftUI
-import Swinject
-
-extension Calibrations {
-    struct RootView: BaseView {
-        let resolver: Resolver
-        @StateObject var state = StateModel()
-
-        private var formatter: NumberFormatter {
-            let formatter = NumberFormatter()
-            formatter.numberStyle = .decimal
-            formatter.maximumFractionDigits = 2
-            return formatter
-        }
-
-        private var dateFormatter: DateFormatter {
-            let formatter = DateFormatter()
-            formatter.timeStyle = .short
-            formatter.dateStyle = .short
-            return formatter
-        }
-
-        var body: some View {
-            GeometryReader { geo in
-                Form {
-                    Section(header: Text("Add calibration")) {
-                        HStack {
-                            Text("Meter glucose")
-                            Spacer()
-                            DecimalTextField(
-                                "0",
-                                value: $state.newCalibration,
-                                formatter: formatter,
-                                autofocus: false,
-                                cleanInput: true
-                            )
-                            Text(state.units.rawValue).foregroundColor(.secondary)
-                        }
-                        Button {
-                            state.addCalibration()
-                        }
-                        label: { Text("Add") }
-                            .disabled(state.newCalibration <= 0)
-                    }
-
-                    Section(header: Text("Info")) {
-                        HStack {
-                            Text("Slope")
-                            Spacer()
-                            Text(formatter.string(from: state.slope as NSNumber)!)
-                        }
-                        HStack {
-                            Text("Intercept")
-                            Spacer()
-                            Text(formatter.string(from: state.intercept as NSNumber)!)
-                        }
-                    }
-
-                    Section(header: Text("Remove")) {
-                        Button {
-                            state.removeLast()
-                        }
-                        label: { Text("Remove Last") }
-                            .disabled(state.calibrations.isEmpty)
-
-                        Button {
-                            state.removeAll()
-                        }
-                        label: { Text("Remove All") }
-                            .disabled(state.calibrations.isEmpty)
-                        List {
-                            ForEach(state.items) { item in
-                                HStack {
-                                    Text(dateFormatter.string(from: item.calibration.date))
-                                    Spacer()
-                                    VStack(alignment: .leading) {
-                                        Text("raw: \(item.calibration.x)")
-                                            .font(.caption2)
-                                            .foregroundColor(.secondary)
-                                        Text("value: \(item.calibration.y)")
-                                            .font(.caption2)
-                                            .foregroundColor(.secondary)
-                                    }
-                                }
-
-                            }.onDelete(perform: delete)
-                        }
-                    }
-
-                    if state.calibrations.isNotEmpty {
-                        Section(header: Text("Chart")) {
-                            CalibrationsChart().environmentObject(state)
-                                .frame(minHeight: geo.size.width)
-                        }
-                    }
-                }
-            }
-            .onAppear(perform: configureView)
-            .navigationTitle("Calibrations")
-            .navigationBarItems(trailing: EditButton().disabled(state.calibrations.isEmpty))
-            .navigationBarTitleDisplayMode(.automatic)
-        }
-
-        private func delete(at offsets: IndexSet) {
-            state.removeAtIndex(offsets[offsets.startIndex])
-        }
-    }
-}

+ 0 - 5
FreeAPS/Sources/Modules/LibreConfig/LibreConfigDataFlow.swift

@@ -1,5 +0,0 @@
-enum LibreConfig {
-    enum Config {}
-}
-
-protocol LibreConfigProvider {}

+ 0 - 3
FreeAPS/Sources/Modules/LibreConfig/LibreConfigProvider.swift

@@ -1,3 +0,0 @@
-extension LibreConfig {
-    final class Provider: BaseProvider, LibreConfigProvider {}
-}

+ 0 - 17
FreeAPS/Sources/Modules/LibreConfig/LibreConfigStateModel.swift

@@ -1,17 +0,0 @@
-import HealthKit
-import SwiftUI
-
-extension LibreConfig {
-    final class StateModel: BaseStateModel<Provider> {
-        @Injected() var source: LibreTransmitterSource!
-
-        @Published var configured = false
-
-        var unit = HKUnit.millimolesPerLiter
-
-        override func subscribe() {
-            configured = source.manager != nil
-            unit = settingsManager.settings.units == .mmolL ? .millimolesPerLiter : .milligramsPerDeciliter
-        }
-    }
-}

+ 0 - 36
FreeAPS/Sources/Modules/LibreConfig/View/LibreConfigRootView.swift

@@ -1,36 +0,0 @@
-import LibreTransmitter
-import SwiftUI
-import Swinject
-
-extension LibreConfig {
-    struct RootView: BaseView {
-        let resolver: Resolver
-        @StateObject var state = StateModel()
-
-        var body: some View {
-            Group {
-                if state.configured, let manager = state.source.manager {
-                    LibreTransmitterSettingsView(
-                        manager: manager,
-                        glucoseUnit: state.unit
-                    ) {
-                        self.state.source.manager = nil
-                        self.state.configured = false
-                    } completion: {
-                        state.hideModal()
-                    }
-                } else {
-                    LibreTransmitterSetupView { manager in
-                        self.state.source.manager = manager
-                        self.state.configured = true
-                    } completion: {
-                        state.hideModal()
-                    }
-                }
-            }
-            .navigationBarTitle("")
-            .navigationBarHidden(true)
-            .onAppear(perform: configureView)
-        }
-    }
-}

+ 0 - 6
FreeAPS/Sources/Router/Screen.swift

@@ -22,8 +22,6 @@ enum Screen: Identifiable, Hashable {
     case dataTable
     case cgm
     case healthkit
-    case libreConfig
-    case calibrations
     case notificationsConfig
     case fpuConfig
     case iconConfig
@@ -79,10 +77,6 @@ extension Screen {
             CGM.RootView(resolver: resolver)
         case .healthkit:
             AppleHealthKit.RootView(resolver: resolver)
-        case .libreConfig:
-            LibreConfig.RootView(resolver: resolver)
-        case .calibrations:
-            Calibrations.RootView(resolver: resolver)
         case .notificationsConfig:
             NotificationsConfig.RootView(resolver: resolver)
         case .fpuConfig:

+ 1 - 0
G7SensorKit

@@ -0,0 +1 @@
+Subproject commit 83d8aafd7fc7630e51d7292bbb287d865aba72c7

+ 1 - 0
LibreTransmitter

@@ -0,0 +1 @@
+Subproject commit c01eba63e94e9f6f2841a8835680c4e39c61b18d

+ 1 - 0
LoopKit

@@ -0,0 +1 @@
+Subproject commit 2f535b3ca46825e82e0dd1b5ef9daccd53a3f0ca

+ 1 - 0
MinimedKit

@@ -0,0 +1 @@
+Subproject commit d29ee3611a31be1096c3886835e5fef081f8b211

+ 1 - 0
OmniBLE

@@ -0,0 +1 @@
+Subproject commit bfe2795cb4933c5ecc6f6d8040aefc4b281563de

+ 1 - 0
OmniKit

@@ -0,0 +1 @@
+Subproject commit a78fdcd96deb22638f8a3451468b0b18b70fd1d9

+ 1 - 0
RileyLinkKit

@@ -0,0 +1 @@
+Subproject commit a0e419da314d0ad42b41ccb04af73cd1fbf41257

+ 1 - 0
dexcom-share-client-swift

@@ -0,0 +1 @@
+Subproject commit 0f93513d5c306342c4d3ce85f5ab062da1e1b145