diff --git a/.gitmodules b/.gitmodules index 43705f607b..5e724b4e08 100644 --- a/.gitmodules +++ b/.gitmodules @@ -34,6 +34,3 @@ path = LibreTransmitter url = https://github.com/LoopKit/LibreTransmitter.git branch = main -[submodule "TidepoolService"] - path = TidepoolService - url = https://github.com/LoopKit/TidepoolService.git diff --git a/BuildDetails.plist b/BuildDetails.plist deleted file mode 100644 index 6a06c7327b..0000000000 --- a/BuildDetails.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - TidepoolServiceClientId - diy-loop - - diff --git a/FreeAPS.xcodeproj/project.pbxproj b/FreeAPS.xcodeproj/project.pbxproj index 25c6b2462a..b606d88dc8 100644 --- a/FreeAPS.xcodeproj/project.pbxproj +++ b/FreeAPS.xcodeproj/project.pbxproj @@ -325,10 +325,6 @@ CC41E29A2B1E1F460070974F /* HistoryLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC41E2992B1E1F460070974F /* HistoryLayout.swift */; }; CC6C406E2ACDD69E009B8058 /* RawFetchedProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC6C406D2ACDD69E009B8058 /* RawFetchedProfile.swift */; }; CD78BB94E43B249D60CC1A1B /* NotificationsConfigRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22963BD06A9C83959D4914E4 /* NotificationsConfigRootView.swift */; }; - CE1F6DD92BADF4620064EB8D /* PluginManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F6DD82BADF4620064EB8D /* PluginManagerTests.swift */; }; - CE1F6DDB2BAE08B60064EB8D /* TidepoolManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F6DDA2BAE08B60064EB8D /* TidepoolManager.swift */; }; - CE1F6DE72BAF1A180064EB8D /* BuildDetails.plist in Resources */ = {isa = PBXBuildFile; fileRef = CE1F6DE62BAF1A180064EB8D /* BuildDetails.plist */; }; - CE1F6DE92BAF37C90064EB8D /* TidePoolConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F6DE82BAF37C90064EB8D /* TidePoolConfigView.swift */; }; CE1F2B9A2B011CC0002EDCA0 /* AutoISFConfDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F2B992B011CC0002EDCA0 /* AutoISFConfDataFlow.swift */; }; CE1F2B9C2B011CCF002EDCA0 /* AutoISFConfProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F2B9B2B011CCF002EDCA0 /* AutoISFConfProvider.swift */; }; CE1F2B9E2B011CDE002EDCA0 /* AutoISFConfStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F2B9D2B011CDE002EDCA0 /* AutoISFConfStateModel.swift */; }; @@ -380,13 +376,6 @@ CEB434E728B9053300B70274 /* LoopUIColorPalette+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB434E628B9053300B70274 /* LoopUIColorPalette+Default.swift */; }; CEB434FD28B90B7C00B70274 /* SwiftCharts in Frameworks */ = {isa = PBXBuildFile; productRef = CEB434FC28B90B7C00B70274 /* SwiftCharts */; }; CEB434FE28B90B8C00B70274 /* SwiftCharts in Embed Frameworks */ = {isa = PBXBuildFile; productRef = CEB434FC28B90B7C00B70274 /* SwiftCharts */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - CEE9A6552BBB418300EB5194 /* CalibrationsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A64F2BBB418300EB5194 /* CalibrationsProvider.swift */; }; - CEE9A6562BBB418300EB5194 /* CalibrationsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A6512BBB418300EB5194 /* CalibrationsRootView.swift */; }; - CEE9A6572BBB418300EB5194 /* CalibrationsChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A6522BBB418300EB5194 /* CalibrationsChart.swift */; }; - CEE9A6582BBB418300EB5194 /* CalibrationsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A6532BBB418300EB5194 /* CalibrationsStateModel.swift */; }; - CEE9A6592BBB418300EB5194 /* CalibrationsDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A6542BBB418300EB5194 /* CalibrationsDataFlow.swift */; }; - CEE9A65C2BBB41C800EB5194 /* CalibrationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A65B2BBB41C800EB5194 /* CalibrationService.swift */; }; - CEE9A65E2BBC9F6500EB5194 /* CalibrationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9A65D2BBC9F6500EB5194 /* CalibrationsTests.swift */; }; CECCB4262BDBDCF7006E41C4 /* carbPresetResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCB4252BDBDCF7006E41C4 /* carbPresetResult.swift */; }; CECCB4222BDB85BC006E41C4 /* ListCarbsPresetIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCB4212BDB85BC006E41C4 /* ListCarbsPresetIntent.swift */; }; D2165E9D78EFF692C1DED1C6 /* AddTempTargetDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8A42073A2D03A278914448 /* AddTempTargetDataFlow.swift */; }; @@ -911,10 +900,6 @@ CE1F2B9B2B011CCF002EDCA0 /* AutoISFConfProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoISFConfProvider.swift; sourceTree = ""; }; CE1F2B9D2B011CDE002EDCA0 /* AutoISFConfStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoISFConfStateModel.swift; sourceTree = ""; }; CE1F2BA02B011CF5002EDCA0 /* AutoISFConfRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoISFConfRootView.swift; sourceTree = ""; }; - CE1F6DD82BADF4620064EB8D /* PluginManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginManagerTests.swift; sourceTree = ""; }; - CE1F6DDA2BAE08B60064EB8D /* TidepoolManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TidepoolManager.swift; sourceTree = ""; }; - CE1F6DE62BAF1A180064EB8D /* BuildDetails.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = BuildDetails.plist; sourceTree = ""; }; - CE1F6DE82BAF37C90064EB8D /* TidePoolConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TidePoolConfigView.swift; sourceTree = ""; }; CE2FAD39297D93F0001A872C /* BloodGlucoseExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BloodGlucoseExtensions.swift; sourceTree = ""; }; CE398D012977349800DF218F /* CryptoKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoKit.framework; path = System/Library/Frameworks/CryptoKit.framework; sourceTree = SDKROOT; }; CE398D17297C9EE800DF218F /* G7SensorKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = G7SensorKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -967,13 +952,6 @@ CEC751D729D88262006E9D24 /* MinimedKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MinimedKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CECCB4252BDBDCF7006E41C4 /* carbPresetResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = carbPresetResult.swift; sourceTree = ""; }; CECCB4212BDB85BC006E41C4 /* ListCarbsPresetIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCarbsPresetIntent.swift; sourceTree = ""; }; - CEE9A64F2BBB418300EB5194 /* CalibrationsProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalibrationsProvider.swift; sourceTree = ""; }; - CEE9A6512BBB418300EB5194 /* CalibrationsRootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalibrationsRootView.swift; sourceTree = ""; }; - CEE9A6522BBB418300EB5194 /* CalibrationsChart.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalibrationsChart.swift; sourceTree = ""; }; - CEE9A6532BBB418300EB5194 /* CalibrationsStateModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalibrationsStateModel.swift; sourceTree = ""; }; - CEE9A6542BBB418300EB5194 /* CalibrationsDataFlow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalibrationsDataFlow.swift; sourceTree = ""; }; - CEE9A65B2BBB41C800EB5194 /* CalibrationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalibrationService.swift; sourceTree = ""; }; - CEE9A65D2BBC9F6500EB5194 /* CalibrationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalibrationsTests.swift; sourceTree = ""; }; CFCFE0781F9074C2917890E8 /* ManualTempBasalStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalStateModel.swift; sourceTree = ""; }; D0BDC6993C1087310EDFC428 /* CREditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CREditorRootView.swift; sourceTree = ""; }; D295A3F870E826BE371C0BB5 /* AutotuneConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AutotuneConfigStateModel.swift; sourceTree = ""; }; @@ -1297,7 +1275,6 @@ F2159A472BA60A0300A0B716 /* ContactTrick */, 195D80B22AF696EE00D25097 /* Dynamic */, BD7DA9A32AE06DBA00601B20 /* BolusCalculatorConfig */, - CEE9A64D2BBB411C00EB5194 /* Calibrations */, 190EBCC229FF134900BA767D /* StatConfig */, 19F95FF129F10F9C00314DDC /* Stat */, CE94597C29E9E1CD0047C9C6 /* WatchConfig */, @@ -1426,7 +1403,6 @@ isa = PBXGroup; children = ( 3811DE3C25C9D4A100A708ED /* SettingsRootView.swift */, - CE1F6DE82BAF37C90064EB8D /* TidePoolConfigView.swift */, ); path = View; sourceTree = ""; @@ -1468,7 +1444,6 @@ 3811DE9725C9D88300A708ED /* NightscoutManager.swift */, 38FE826925CC82DB001FF17A /* NetworkService.swift */, 38FE826C25CC8461001FF17A /* NightscoutAPI.swift */, - CE1F6DDA2BAE08B60064EB8D /* TidepoolManager.swift */, ); path = Network; sourceTree = ""; @@ -1634,7 +1609,6 @@ 3856933F270B57A00002C50D /* CGM */ = { isa = PBXGroup; children = ( - CEE9A65A2BBB41AD00EB5194 /* Calibrations */, F816825F28DB441800054060 /* BluetoothTransmitter.swift */, F816825D28DB441200054060 /* HeartBeatManager.swift */, 38569346270B5DFB0002C50D /* AppGroupSource.swift */, @@ -1671,7 +1645,6 @@ 388E594F25AD948C0019842D = { isa = PBXGroup; children = ( - CE1F6DE62BAF1A180064EB8D /* BuildDetails.plist */, FEFA5C0D299F810B00765C17 /* Core_Data.xcdatamodeld */, 38F3783A2613555C009DB701 /* Config.xcconfig */, 3818AA42274BBC1100843DB3 /* ConfigOverride.xcconfig */, @@ -1989,8 +1962,6 @@ children = ( 38FCF3F125E9028E0078B0D1 /* Info.plist */, 38FCF3F825E902C20078B0D1 /* FileStorageTests.swift */, - CE1F6DD82BADF4620064EB8D /* PluginManagerTests.swift */, - CEE9A65D2BBC9F6500EB5194 /* CalibrationsTests.swift */, ); path = FreeAPSTests; sourceTree = ""; @@ -2412,34 +2383,6 @@ path = Bluetooth; sourceTree = ""; }; - CEE9A64D2BBB411C00EB5194 /* Calibrations */ = { - isa = PBXGroup; - children = ( - CEE9A6542BBB418300EB5194 /* CalibrationsDataFlow.swift */, - CEE9A64F2BBB418300EB5194 /* CalibrationsProvider.swift */, - CEE9A6532BBB418300EB5194 /* CalibrationsStateModel.swift */, - CEE9A6502BBB418300EB5194 /* View */, - ); - path = Calibrations; - sourceTree = ""; - }; - CEE9A6502BBB418300EB5194 /* View */ = { - isa = PBXGroup; - children = ( - CEE9A6512BBB418300EB5194 /* CalibrationsRootView.swift */, - CEE9A6522BBB418300EB5194 /* CalibrationsChart.swift */, - ); - path = View; - sourceTree = ""; - }; - CEE9A65A2BBB41AD00EB5194 /* Calibrations */ = { - isa = PBXGroup; - children = ( - CEE9A65B2BBB41C800EB5194 /* CalibrationService.swift */, - ); - path = Calibrations; - sourceTree = ""; - }; D533BF261CDC1C3F871E7BFD /* NightscoutConfig */ = { isa = PBXGroup; children = ( @@ -2779,7 +2722,6 @@ buildActionMask = 2147483647; files = ( 198377D2266BFFF6004DE65E /* Localizable.strings in Resources */, - CE1F6DE72BAF1A180064EB8D /* BuildDetails.plist in Resources */, 38DF178D27733E6800B3528F /* snow.sks in Resources */, 388E597225AD9CF10019842D /* json in Resources */, 38DF178E27733E6800B3528F /* Assets.xcassets in Resources */, @@ -2928,7 +2870,6 @@ 383420D925FFEB3F002D46C1 /* Popup.swift in Sources */, 3811DE3025C9D49500A708ED /* HomeStateModel.swift in Sources */, 38BF021725E7CBBC00579895 /* PumpManagerExtensions.swift in Sources */, - CEE9A6552BBB418300EB5194 /* CalibrationsProvider.swift in Sources */, 19F95FF529F10FCF00314DDC /* StatProvider.swift in Sources */, 38F3B2EF25ED8E2A005C48AA /* TempTargetsStorage.swift in Sources */, 19B0EF2128F6D66200069496 /* Statistics.swift in Sources */, @@ -2949,7 +2890,6 @@ 382C133725F13A1E00715CE1 /* InsulinSensitivities.swift in Sources */, 19D466A529AA2BD4004D5F33 /* FPUConfigProvider.swift in Sources */, 383948D625CD4D8900E91849 /* FileStorage.swift in Sources */, - CEE9A6572BBB418300EB5194 /* CalibrationsChart.swift in Sources */, 3811DE4125C9D4A100A708ED /* SettingsRootView.swift in Sources */, 38192E04261B82FA0094D973 /* ReachabilityManager.swift in Sources */, 38E44539274E411700EC9A94 /* Disk+UIImage.swift in Sources */, @@ -2958,10 +2898,8 @@ CECCB4262BDBDCF7006E41C4 /* carbPresetResult.swift in Sources */, F2159A542BA6207F00A0B716 /* ContactTrickEntry.swift in Sources */, 38569348270B5DFB0002C50D /* GlucoseSource.swift in Sources */, - CEE9A6582BBB418300EB5194 /* CalibrationsStateModel.swift in Sources */, CEB434E328B8F9DB00B70274 /* BluetoothStateManager.swift in Sources */, 3811DE4225C9D4A100A708ED /* SettingsDataFlow.swift in Sources */, - CEE9A6562BBB418300EB5194 /* CalibrationsRootView.swift in Sources */, 3811DE2525C9D48300A708ED /* MainRootView.swift in Sources */, CE94598229E9E3D30047C9C6 /* WatchConfigProvider.swift in Sources */, 38E44535274E411700EC9A94 /* Disk+Data.swift in Sources */, @@ -3000,7 +2938,6 @@ 38569347270B5DFB0002C50D /* CGMType.swift in Sources */, 3821ED4C25DD18BA00BC42AD /* Constants.swift in Sources */, 384E803425C385E60086DB71 /* JavaScriptWorker.swift in Sources */, - CE1F6DE92BAF37C90064EB8D /* TidePoolConfigView.swift in Sources */, 3811DE5D25C9D4D500A708ED /* Publisher.swift in Sources */, E00EEC0727368630002FF094 /* APSAssembly.swift in Sources */, 38B4F3AF25E2979F00E76A18 /* IndexedCollection.swift in Sources */, @@ -3015,7 +2952,6 @@ CE95BF5A2BA62E4A00DC3DE3 /* PluginSource.swift in Sources */, 3811DE5C25C9D4D500A708ED /* Formatters.swift in Sources */, 3871F39F25ED895A0013ECB5 /* Decimal+Extensions.swift in Sources */, - CEE9A6592BBB418300EB5194 /* CalibrationsDataFlow.swift in Sources */, 3811DE3525C9D49500A708ED /* HomeRootView.swift in Sources */, 49CA5A182BDA385E001F0D3A /* KetoProtectConfRootView.swift in Sources */, 38E98A2925F52C9300C0CED0 /* Error+Extensions.swift in Sources */, @@ -3086,7 +3022,6 @@ CE7CA3532A064973004BE681 /* tempPresetEntity.swift in Sources */, D6DEC113821A7F1056C4AA1E /* NightscoutConfigDataFlow.swift in Sources */, 38E98A3025F52FF700C0CED0 /* Config.swift in Sources */, - CE1F6DDB2BAE08B60064EB8D /* TidepoolManager.swift in Sources */, BD2B464E0745FBE7B79913F4 /* NightscoutConfigProvider.swift in Sources */, 9825E5E923F0B8FA80C8C7C7 /* NightscoutConfigStateModel.swift in Sources */, CE1F2B9E2B011CDE002EDCA0 /* AutoISFConfStateModel.swift in Sources */, @@ -3153,7 +3088,6 @@ 69B9A368029F7EB39F525422 /* CREditorStateModel.swift in Sources */, 38E44538274E411700EC9A94 /* Disk+[Data].swift in Sources */, 98641AF4F92123DA668AB931 /* CREditorRootView.swift in Sources */, - CEE9A65C2BBB41C800EB5194 /* CalibrationService.swift in Sources */, 38E4453D274E411700EC9A94 /* Disk+Errors.swift in Sources */, 38E98A2325F52C9300C0CED0 /* Signpost.swift in Sources */, 495068AA2BDFEF1D0048FF3B /* CarbPresetIntentRequest.swift in Sources */, @@ -3282,8 +3216,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CEE9A65E2BBC9F6500EB5194 /* CalibrationsTests.swift in Sources */, - CE1F6DD92BADF4620064EB8D /* PluginManagerTests.swift in Sources */, 38FCF3F925E902C20078B0D1 /* FileStorageTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/FreeAPS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/FreeAPS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 44ce21ec11..9c00041f21 100644 --- a/FreeAPS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/FreeAPS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,68 +1,61 @@ { - "pins" : [ - { - "identity" : "mkringprogressview", - "kind" : "remoteSourceControl", - "location" : "https://github.com/maxkonovalov/MKRingProgressView.git", - "state" : { - "branch" : "master", - "revision" : "660888aab1d2ab0ed7eb9eb53caec12af4955fa7" + "object": { + "pins": [ + { + "package": "Alamofire", + "repositoryURL": "https://github.com/Alamofire/Alamofire", + "state": { + "branch": null, + "revision": "f96b619bcb2383b43d898402283924b80e2c4bae", + "version": "5.4.3" + } + }, + { + "package": "Disk", + "repositoryURL": "https://github.com/saoudrizwan/Disk", + "state": { + "branch": null, + "revision": "b0cb4fdf23e51849cc2460bdc6de795c3bcca99d", + "version": "0.6.4" + } + }, + { + "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": "SwiftDate", + "repositoryURL": "https://github.com/malcommac/SwiftDate", + "state": { + "branch": null, + "revision": "6190d0cefff3013e77ed567e6b074f324e5c5bf5", + "version": "6.3.1" + } + }, + { + "package": "Swinject", + "repositoryURL": "https://github.com/Swinject/Swinject", + "state": { + "branch": null, + "revision": "8a76d2c74bafbb455763487cc6a08e91bad1f78b", + "version": "2.7.1" + } } - }, - { - "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" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", - "version" : "9.0.9" - } - }, - { - "identity" : "swinject", - "kind" : "remoteSourceControl", - "location" : "https://github.com/Swinject/Swinject", - "state" : { - "revision" : "8a76d2c74bafbb455763487cc6a08e91bad1f78b", - "version" : "2.7.1" - } - } - ], - "version" : 2 + ] + }, + "version": 1 } diff --git a/FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme b/FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme index 42cb16b9ed..bcc727971e 100644 --- a/FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme +++ b/FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPS X.xcscheme @@ -216,20 +216,6 @@ ReferencedContainer = "container:OmniBLE/OmniBLE.xcodeproj"> - - - - + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> + skipped = "NO"> - - diff --git a/FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved b/FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved index 21ee8d2c82..7db1d459b3 100644 --- a/FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -68,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SwiftKickMobile/SwiftMessages", "state" : { - "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", - "version" : "9.0.9" + "revision" : "b29dd21090b708aa0ae9ecbaf6e2d0487028dc3f", + "version" : "9.0.6" } }, { @@ -80,15 +80,6 @@ "revision" : "0b0fa300d0fe24be810750272e0e7ea1971dff90", "version" : "2.8.5" } - }, - { - "identity" : "tidepoolkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/tidepool-org/TidepoolKit", - "state" : { - "branch" : "dev", - "revision" : "b8185353c0f46a055f6d5681bb3f18ec86a5b974" - } } ], "version" : 2 diff --git a/FreeAPS/Sources/APS/CGM/Calibrations/CalibrationService.swift b/FreeAPS/Sources/APS/CGM/Calibrations/CalibrationService.swift deleted file mode 100644 index 99af475269..0000000000 --- a/FreeAPS/Sources/APS/CGM/Calibrations/CalibrationService.swift +++ /dev/null @@ -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: Int) -> 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: Int) -> 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: Int) -> Double { - (intercept + slope * Double(x)).clamped(Config.minValue ... Config.maxValue) - } -} diff --git a/FreeAPS/Sources/APS/CGM/PluginSource.swift b/FreeAPS/Sources/APS/CGM/PluginSource.swift index 07233bc9ca..3485b08790 100644 --- a/FreeAPS/Sources/APS/CGM/PluginSource.swift +++ b/FreeAPS/Sources/APS/CGM/PluginSource.swift @@ -103,13 +103,7 @@ extension PluginSource: CGMManagerDelegate { dispatchPrecondition(condition: .onQueue(processQueue)) // TODO: Events in APS ? // currently only display in log the date of the event - events.forEach { event in - debug(.deviceManager, "events from CGM at \(event.date)") - - if event.type == .sensorStart { - self.glucoseManager?.removeCalibrations() - } - } + events.forEach { debug(.deviceManager, "events from CGM at \($0.date)") } } func startDateToFilterNewData(for _: CGMManager) -> Date? { @@ -132,7 +126,6 @@ extension PluginSource: CGMManagerDelegate { } func cgmManager(_: CGMManager, didUpdate status: CGMManagerStatus) { - debug(.deviceManager, "DEBUG DID UPDATE STATE") processQueue.async { if self.cgmHasValidSensorSession != status.hasValidSensorSession { self.cgmHasValidSensorSession = status.hasValidSensorSession diff --git a/FreeAPS/Sources/APS/FetchGlucoseManager.swift b/FreeAPS/Sources/APS/FetchGlucoseManager.swift index 2b7b6e36ca..1b7821de7e 100644 --- a/FreeAPS/Sources/APS/FetchGlucoseManager.swift +++ b/FreeAPS/Sources/APS/FetchGlucoseManager.swift @@ -11,7 +11,6 @@ protocol FetchGlucoseManager: SourceInfoProvider { func refreshCGM() func updateGlucoseSource(cgmGlucoseSourceType: CGMType, cgmGlucosePluginId: String, newManager: CGMManagerUI?) func deleteGlucoseSource() - func removeCalibrations() var glucoseSource: GlucoseSource! { get } var cgmManager: CGMManagerUI? { get } var cgmGlucoseSourceType: CGMType? { get set } @@ -30,13 +29,11 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { private let processQueue = DispatchQueue(label: "BaseGlucoseManager.processQueue") @Injected() var glucoseStorage: GlucoseStorage! @Injected() var nightscoutManager: NightscoutManager! - @Injected() var tidePoolService: TidePoolManager! @Injected() var apsManager: APSManager! @Injected() var settingsManager: SettingsManager! @Injected() var healthKitManager: HealthKitManager! @Injected() var deviceDataManager: DeviceDataManager! @Injected() var pluginCGMManager: PluginManager! - @Injected() var calibrationService: CalibrationService! private var lifetime = Lifetime() private let timer = DispatchTimer(timeInterval: 1.minutes.timeInterval) @@ -70,10 +67,6 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { var glucoseSource: GlucoseSource! - func removeCalibrations() { - calibrationService.removeAllCalibrations() - } - func deleteGlucoseSource() { cgmManager = nil updateGlucoseSource( @@ -83,11 +76,6 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { } func updateGlucoseSource(cgmGlucoseSourceType: CGMType, cgmGlucosePluginId: String, newManager: CGMManagerUI?) { - // if changed, remove all calibrations - if self.cgmGlucoseSourceType != cgmGlucoseSourceType || self.cgmGlucosePluginId != cgmGlucosePluginId { - removeCalibrations() - } - self.cgmGlucoseSourceType = cgmGlucoseSourceType self.cgmGlucosePluginId = cgmGlucosePluginId @@ -99,10 +87,12 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { if let manager = newManager { cgmManager = manager - removeCalibrations() } else if self.cgmGlucoseSourceType == .plugin, cgmManager == nil, let rawCGMManager = rawCGMManager { cgmManager = cgmManagerFromRawValue(rawCGMManager) } +// } else if self.cgmGlucoseSourceType == .plugin, self.cgmGlucosePluginId != , self.cgmGlucosePluginId != cgmManager?.pluginIdentifier { +// cgmManager = nil +// } switch self.cgmGlucoseSourceType { case nil, @@ -163,10 +153,7 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { } private func glucoseStoreAndHeartDecision(syncDate: Date, glucose: [BloodGlucose], glucoseFromHealth: [BloodGlucose] = []) { - // calibration add if required only for sensor - let newGlucose = overcalibrate(entries: glucose) - - let allGlucose = newGlucose + glucoseFromHealth + let allGlucose = glucose + glucoseFromHealth var filteredByDate: [BloodGlucose] = [] var filtered: [BloodGlucose] = [] @@ -219,7 +206,6 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { deviceDataManager.heartbeat(date: Date()) nightscoutManager.uploadGlucose() - tidePoolService.uploadGlucose(device: cgmManager?.cgmManagerStatus.device) // end of the BG tasks if let backgroundTask = backGroundFetchBGTaskID { @@ -272,23 +258,6 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { func sourceInfo() -> [String: Any]? { glucoseSource.sourceInfo() } - - private func overcalibrate(entries: [BloodGlucose]) -> [BloodGlucose] { - // overcalibrate - var overcalibration: ((Int) -> (Double))? - processQueue.sync { overcalibration = calibrationService.calibrate } - - if let overcalibration = overcalibration { - return entries.map { entry in - var entry = entry - entry.glucose = Int(overcalibration(entry.glucose!)) - entry.sgv = Int(overcalibration(entry.sgv!)) - return entry - } - } else { - return entries - } - } } extension CGMManager { diff --git a/FreeAPS/Sources/APS/PluginManager.swift b/FreeAPS/Sources/APS/PluginManager.swift index de6e211ece..8f66f4f9a5 100644 --- a/FreeAPS/Sources/APS/PluginManager.swift +++ b/FreeAPS/Sources/APS/PluginManager.swift @@ -6,10 +6,8 @@ import Swinject protocol PluginManager { var availablePumpManagers: [PumpManagerDescriptor] { get } var availableCGMManagers: [CGMManagerDescriptor] { get } - var availableServices: [ServiceDescriptor] { get } func getPumpManagerTypeByIdentifier(_ identifier: String) -> PumpManagerUI.Type? func getCGMManagerTypeByIdentifier(_ identifier: String) -> CGMManagerUI.Type? - func getServiceTypeByIdentifier(_ identifier: String) -> ServiceUI.Type? } class BasePluginManager: Injectable, PluginManager { diff --git a/FreeAPS/Sources/Assemblies/APSAssembly.swift b/FreeAPS/Sources/Assemblies/APSAssembly.swift index 4fc3eacb43..d5d3253ce2 100644 --- a/FreeAPS/Sources/Assemblies/APSAssembly.swift +++ b/FreeAPS/Sources/Assemblies/APSAssembly.swift @@ -10,6 +10,5 @@ final class APSAssembly: Assembly { container.register(FetchAnnouncementsManager.self) { r in BaseFetchAnnouncementsManager(resolver: r) } container.register(BluetoothStateManager.self) { r in BaseBluetoothStateManager(resolver: r) } container.register(PluginManager.self) { r in BasePluginManager(resolver: r) } - container.register(CalibrationService.self) { r in BaseCalibrationService(resolver: r) } } } diff --git a/FreeAPS/Sources/Assemblies/NetworkAssembly.swift b/FreeAPS/Sources/Assemblies/NetworkAssembly.swift index d3c63eec7b..619b816695 100644 --- a/FreeAPS/Sources/Assemblies/NetworkAssembly.swift +++ b/FreeAPS/Sources/Assemblies/NetworkAssembly.swift @@ -8,6 +8,5 @@ final class NetworkAssembly: Assembly { } container.register(NightscoutManager.self) { r in BaseNightscoutManager(resolver: r) } - container.register(TidePoolManager.self) { r in BaseTidePoolManager(resolver: r) } } } diff --git a/FreeAPS/Sources/Models/BloodGlucose.swift b/FreeAPS/Sources/Models/BloodGlucose.swift index 094ff3e046..ad4307f40c 100644 --- a/FreeAPS/Sources/Models/BloodGlucose.swift +++ b/FreeAPS/Sources/Models/BloodGlucose.swift @@ -1,6 +1,4 @@ import Foundation -import HealthKit -import LoopKit struct BloodGlucose: JSON, Identifiable, Hashable { enum Direction: String, JSON { @@ -91,14 +89,3 @@ extension BloodGlucose: SavitzkyGolaySmoothable { } } } - -extension BloodGlucose { - func convertStoredGlucoseSample(device: HKDevice?) -> StoredGlucoseSample { - StoredGlucoseSample( - syncIdentifier: id, - startDate: dateString.date, - quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose!)), - device: device - ) - } -} diff --git a/FreeAPS/Sources/Models/CarbsEntry.swift b/FreeAPS/Sources/Models/CarbsEntry.swift index 43d479496e..0394644edb 100644 --- a/FreeAPS/Sources/Models/CarbsEntry.swift +++ b/FreeAPS/Sources/Models/CarbsEntry.swift @@ -1,5 +1,4 @@ import Foundation -import LoopKit struct CarbsEntry: JSON, Equatable, Hashable { let id: String? @@ -40,25 +39,3 @@ extension CarbsEntry { case fpuID } } - -extension CarbsEntry { - func convertSyncCarb(operation: LoopKit.Operation = .create) -> SyncCarbObject { - SyncCarbObject( - absorptionTime: nil, - createdByCurrentApp: true, - foodType: nil, - grams: Double(carbs), - startDate: createdAt, - uuid: UUID(uuidString: id!), - provenanceIdentifier: enteredBy ?? "", - syncIdentifier: id, - syncVersion: nil, - userCreatedDate: nil, - userUpdatedDate: nil, - userDeletedDate: nil, - operation: operation, - addedDate: nil, - supercededDate: nil - ) - } -} diff --git a/FreeAPS/Sources/Models/PumpHistoryEvent.swift b/FreeAPS/Sources/Models/PumpHistoryEvent.swift index 583a15639e..f9c4cc6a4a 100644 --- a/FreeAPS/Sources/Models/PumpHistoryEvent.swift +++ b/FreeAPS/Sources/Models/PumpHistoryEvent.swift @@ -1,5 +1,4 @@ import Foundation -import LoopKit struct PumpHistoryEvent: JSON, Equatable { let id: String @@ -95,29 +94,3 @@ extension PumpHistoryEvent { case isExternal } } - -extension EventType { - func mapEventTypeToPumpEventType() -> PumpEventType? { - switch self { - case .prime: - return PumpEventType.prime - case .pumpResume: - return PumpEventType.resume - case .rewind: - return PumpEventType.rewind - case .pumpSuspend: - return PumpEventType.suspend - case .nsBatteryChange, - .pumpBattery: - return PumpEventType.replaceComponent(componentType: .pump) - case .nsInsulinChange: - return PumpEventType.replaceComponent(componentType: .reservoir) - case .nsSiteChange: - return PumpEventType.replaceComponent(componentType: .infusionSet) - case .pumpAlarm: - return PumpEventType.alarm - default: - return nil - } - } -} diff --git a/FreeAPS/Sources/Modules/CGM/CGMStateModel.swift b/FreeAPS/Sources/Modules/CGM/CGMStateModel.swift index 958854089b..c276b34b36 100644 --- a/FreeAPS/Sources/Modules/CGM/CGMStateModel.swift +++ b/FreeAPS/Sources/Modules/CGM/CGMStateModel.swift @@ -23,8 +23,6 @@ extension CGM { @Injected() var cgmManager: FetchGlucoseManager! @Injected() var calendarManager: CalendarManager! @Injected() var pluginCGMManager: PluginManager! - @Injected() private var broadcaster: Broadcaster! - @Injected() var nightscoutManager: NightscoutManager! @Published var setupCGM: Bool = false @Published var cgmCurrent = cgmDefaultName @@ -37,7 +35,6 @@ extension CGM { @Persisted(key: "CalendarManager.currentCalendarID") var storedCalendarID: String? = nil @Published var cgmTransmitterDeviceAddress: String? = nil @Published var listOfCGM: [cgmName] = [] - @Published var url: URL? override func subscribe() { // collect the list of CGM available with plugins and CGMType defined manually @@ -70,17 +67,6 @@ extension CGM { ) } - url = nightscoutManager.cgmURL - switch url?.absoluteString { - case "http://127.0.0.1:1979": - url = URL(string: "spikeapp://")! - case "http://127.0.0.1:17580": - url = URL(string: "diabox://")! - // case CGMType.libreTransmitter.appURL?.absoluteString: - // showModal(for: .libreConfig) - default: break - } - currentCalendarID = storedCalendarID ?? "" calendarIDs = calendarManager.calendarIDs() cgmTransmitterDeviceAddress = UserDefaults.standard.cgmTransmitterDeviceAddress @@ -157,11 +143,6 @@ extension CGM.StateModel: CompletionDelegate { settingsManager.settings.uploadGlucose = cgmManager.shouldSyncToRemoteService // update if required the Glucose source - DispatchQueue.main.async { - self.broadcaster.notify(GlucoseObserver.self, on: .main) { - $0.glucoseDidUpdate([]) - } - } } } diff --git a/FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift b/FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift index 369cdf4e09..5f997fce38 100644 --- a/FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift +++ b/FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift @@ -5,7 +5,6 @@ import Swinject extension CGM { struct RootView: BaseView { let resolver: Resolver - let displayClose: Bool @StateObject var state = StateModel() @State private var setupCGM = false @@ -66,24 +65,6 @@ extension CGM { } } } - if state.cgmCurrent.type == .plugin && state.cgmCurrent.id.contains("Libre") { - Section(header: Text("Calibrations")) { - Text("Calibrations").navigationLink(to: .calibrations, from: self) - } - } - - if state.cgmCurrent.type == .nightscout { - Section(header: Text("Nightscout")) { - if state.url != nil { - Button(state.url!.absoluteString) { - UIApplication.shared.open(state.url!, options: [:], completionHandler: nil) - } - } else { - Text("You need to configure Nightscout URL") - } - } - } - Section(header: Text("Calendar")) { Toggle("Create Events in Calendar", isOn: $state.createCalendarEvents) if state.calendarIDs.isNotEmpty { @@ -118,7 +99,6 @@ extension CGM { .onAppear(perform: configureView) .navigationTitle("CGM") .navigationBarTitleDisplayMode(.automatic) - .navigationBarItems(leading: displayClose ? Button("Close", action: state.hideModal) : nil) .sheet(isPresented: $setupCGM) { if let cgmFetchManager = state.cgmManager, let cgmManager = cgmFetchManager.cgmManager, diff --git a/FreeAPS/Sources/Modules/Calibrations/CalibrationsDataFlow.swift b/FreeAPS/Sources/Modules/Calibrations/CalibrationsDataFlow.swift deleted file mode 100644 index 2f385bdc06..0000000000 --- a/FreeAPS/Sources/Modules/Calibrations/CalibrationsDataFlow.swift +++ /dev/null @@ -1,13 +0,0 @@ -enum Calibrations { - enum Config {} - - struct Item: Hashable, Identifiable { - let calibration: Calibration - - var id: String { - calibration.id.uuidString - } - } -} - -protocol CalibrationsProvider {} diff --git a/FreeAPS/Sources/Modules/Calibrations/CalibrationsProvider.swift b/FreeAPS/Sources/Modules/Calibrations/CalibrationsProvider.swift deleted file mode 100644 index 28e75281fc..0000000000 --- a/FreeAPS/Sources/Modules/Calibrations/CalibrationsProvider.swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Calibrations { - final class Provider: BaseProvider, CalibrationsProvider {} -} diff --git a/FreeAPS/Sources/Modules/Calibrations/CalibrationsStateModel.swift b/FreeAPS/Sources/Modules/Calibrations/CalibrationsStateModel.swift deleted file mode 100644 index be98248f7b..0000000000 --- a/FreeAPS/Sources/Modules/Calibrations/CalibrationsStateModel.swift +++ /dev/null @@ -1,73 +0,0 @@ -import SwiftDate -import SwiftUI - -extension Calibrations { - final class StateModel: BaseStateModel { - @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: (Int) -> 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() - } - } -} diff --git a/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsChart.swift b/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsChart.swift deleted file mode 100644 index 5057058624..0000000000 --- a/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsChart.swift +++ /dev/null @@ -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(Int(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() - } - } -} diff --git a/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift b/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift deleted file mode 100644 index 8bfaead27c..0000000000 --- a/FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift +++ /dev/null @@ -1,109 +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) - } - } - } - } - .dynamicTypeSize(...DynamicTypeSize.xxLarge) - .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]) - } - } -} diff --git a/FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift b/FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift index fe8a2b9035..8fc90b8f1f 100644 --- a/FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift +++ b/FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift @@ -8,7 +8,6 @@ extension DataTable { @Injected() var carbsStorage: CarbsStorage! @Injected() var nightscoutManager: NightscoutManager! @Injected() var healthkitManager: HealthKitManager! - @Injected() var tidePoolManager: TidePoolManager! func pumpHistory() -> [PumpHistoryEvent] { pumpHistoryStorage.recent() @@ -33,28 +32,10 @@ extension DataTable { } func deleteCarbs(_ treatement: Treatment) { - // nightscoutManager.deleteCarbs(treatement, complexMeal: false) - // need to start with tidePool because Nightscout delete data - // probably to revise the logic - // TODO: - tidePoolManager.deleteCarbs( - at: treatement.date, - isFPU: treatement.isFPU, - fpuID: treatement.fpuID, - syncID: treatement.id - ) - - nightscoutManager.deleteCarbs( - at: treatement.date, - isFPU: treatement.isFPU, - fpuID: treatement.fpuID, - syncID: treatement.id - ) + nightscoutManager.deleteCarbs(treatement, complexMeal: false) } func deleteInsulin(_ treatement: Treatment) { - // delete tidePoolManager before NS - TODO - tidePoolManager.deleteInsulin(at: treatement.date) nightscoutManager.deleteInsulin(at: treatement.date) if let id = treatement.idPumpEvent { healthkitManager.deleteInsulin(syncID: id) diff --git a/FreeAPS/Sources/Modules/Home/HomeStateModel.swift b/FreeAPS/Sources/Modules/Home/HomeStateModel.swift index 6a6b5dadc3..ff95902586 100644 --- a/FreeAPS/Sources/Modules/Home/HomeStateModel.swift +++ b/FreeAPS/Sources/Modules/Home/HomeStateModel.swift @@ -10,7 +10,6 @@ extension Home { @Injected() var apsManager: APSManager! @Injected() var nightscoutManager: NightscoutManager! @Injected() var storage: TempTargetsStorage! - @Injected() var fetchGlucoseManager: FetchGlucoseManager! private let timer = DispatchTimer(timeInterval: 5) private(set) var filteredHours = 24 @Published var glucose: [BloodGlucose] = [] @@ -76,7 +75,6 @@ extension Home { @Published var alwaysUseColors: Bool = true @Published var timeSettings: Bool = true @Published var calculatedTins: String = "" - @Published var cgmAvailable: Bool = false private var numberFormatter: NumberFormatter { let formatter = NumberFormatter() @@ -301,7 +299,6 @@ extension Home { self.glucoseDelta = nil } self.alarm = self.provider.glucoseStorage.alarm - cgmAvailable = (fetchGlucoseManager.cgmGlucoseSourceType != CGMType.none) } } @@ -519,7 +516,18 @@ extension Home { } func openCGM() { - showModal(for: .cgmDirect) + guard var url = nightscoutManager.cgmURL else { return } + + switch url.absoluteString { + case "http://127.0.0.1:1979": + url = URL(string: "spikeapp://")! + case "http://127.0.0.1:17580": + url = URL(string: "diabox://")! +// case CGMType.libreTransmitter.appURL?.absoluteString: +// showModal(for: .libreConfig) + default: break + } + UIApplication.shared.open(url, options: [:], completionHandler: nil) } func infoPanelTTPercentage(_ hbt_: Double, _ target: Decimal) -> Decimal { diff --git a/FreeAPS/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift b/FreeAPS/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift index f77e83b934..bc49a6d982 100644 --- a/FreeAPS/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift +++ b/FreeAPS/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift @@ -8,7 +8,6 @@ struct CurrentGlucoseView: View { @Binding var alarm: GlucoseAlarm? @Binding var lowGlucose: Decimal @Binding var highGlucose: Decimal - @Binding var cgmAvailable: Bool @State private var rotationDegrees: Double = 0.0 @State private var angularGradient = AngularGradient(colors: [ @@ -63,7 +62,12 @@ struct CurrentGlucoseView: View { } var body: some View { - if cgmAvailable { + let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902) + + ZStack { + TrendShape(gradient: angularGradient, color: triangleColor) + .rotationEffect(.degrees(rotationDegrees)) + VStack(alignment: .center) { HStack { Text( @@ -73,10 +77,8 @@ struct CurrentGlucoseView: View { .string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! } ?? "--" ) - .font(.title).fontWeight(.bold) - .foregroundColor(alarm == nil ? colorOfGlucose : .loopRed) - - image + .font(.system(size: 40, weight: .bold)) + .foregroundColor(alarm == nil ? colourGlucoseText : .loopRed) } HStack { let minutesAgo = -1 * (recentGlucose?.dateString.timeIntervalSinceNow ?? 0) / 60 @@ -87,7 +89,7 @@ struct CurrentGlucoseView: View { NSLocalizedString("min", comment: "Short form for minutes") + " " ) ) - .font(.caption2).foregroundColor(.secondary) + .font(.caption2).foregroundColor(colorScheme == .dark ? Color.white.opacity(0.9) : Color.secondary) Text( delta @@ -95,20 +97,9 @@ struct CurrentGlucoseView: View { deltaFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! } ?? "--" ) - .font(.caption2).foregroundColor(.secondary) + .font(.caption2).foregroundColor(colorScheme == .dark ? Color.white.opacity(0.9) : Color.secondary) }.frame(alignment: .top) } - } else { - VStack(alignment: .center, spacing: 12) { - HStack - { - // no cgm defined so display a generic CGM - Image(systemName: "sensor.tag.radiowaves.forward.fill").font(.body).imageScale(.large) - } - HStack { - Text("Add CGM").font(.caption).bold() - } - }.frame(alignment: .top) } .onChange(of: recentGlucose?.direction) { newDirection in withAnimation { diff --git a/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift b/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift index cf8387ea87..462da7fd85 100644 --- a/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift +++ b/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift @@ -145,16 +145,23 @@ extension Home { units: $state.units, alarm: $state.alarm, lowGlucose: $state.lowGlucose, - highGlucose: $state.highGlucose, - cgmAvailable: $state.cgmAvailable + highGlucose: $state.highGlucose ) .onTapGesture { - state.openCGM() + if state.alarm == nil { + state.openCGM() + } else { + state.showModal(for: .snooze) + } } .onLongPressGesture { let impactHeavy = UIImpactFeedbackGenerator(style: .heavy) impactHeavy.impactOccurred() - state.showModal(for: .snooze) + if state.alarm == nil { + state.showModal(for: .snooze) + } else { + state.openCGM() + } } } diff --git a/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift b/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift index 1f98f63352..4cf1d64633 100644 --- a/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift +++ b/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift @@ -72,13 +72,6 @@ extension NightscoutConfig { Button("Delete") { state.delete() }.foregroundColor(.red).disabled(state.connecting) } - Section { - Button("Open Nighstcout") { - UIApplication.shared.open(URL(string: state.url)!, options: [:], completionHandler: nil) - } - .disabled(state.url.isEmpty || state.connecting) - } - Section { Toggle("Upload", isOn: $state.isUploadEnabled) if state.isUploadEnabled { diff --git a/FreeAPS/Sources/Modules/Settings/SettingsProvider.swift b/FreeAPS/Sources/Modules/Settings/SettingsProvider.swift index 7918cbd634..571bc1bf8d 100644 --- a/FreeAPS/Sources/Modules/Settings/SettingsProvider.swift +++ b/FreeAPS/Sources/Modules/Settings/SettingsProvider.swift @@ -1,5 +1,3 @@ extension Settings { - final class Provider: BaseProvider, SettingsProvider { - @Injected() var tidePoolManager: TidePoolManager! - } + final class Provider: BaseProvider, SettingsProvider {} } diff --git a/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift b/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift index 417435ca58..ca67d402c5 100644 --- a/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift +++ b/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift @@ -1,5 +1,3 @@ -import LoopKit -import LoopKitUI import SwiftUI extension Settings { @@ -7,14 +5,10 @@ extension Settings { @Injected() private var broadcaster: Broadcaster! @Injected() private var fileManager: FileManager! @Injected() private var nightscoutManager: NightscoutManager! - @Injected() var pluginManager: PluginManager! - @Injected() var fetchCgmManager: FetchGlucoseManager! @Published var closedLoop = false @Published var debugOptions = false @Published var animatedBackground = false - @Published var serviceUIType: ServiceUI.Type? - @Published var setupTidePool = false private(set) var buildNumber = "" private(set) var versionNumber = "" @@ -55,8 +49,6 @@ extension Settings { copyrightNotice = Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String ?? "" subscribeSetting(\.animatedBackground, on: $animatedBackground) { animatedBackground = $0 } - - serviceUIType = pluginManager.getServiceTypeByIdentifier("TidepoolService") } func logItems() -> [URL] { @@ -98,22 +90,3 @@ extension Settings.StateModel: SettingsObserver { debugOptions = settings.debugOptions } } - -extension Settings.StateModel: ServiceOnboardingDelegate { - func serviceOnboarding(didCreateService service: Service) { - debug(.nightscout, "Service with identifier \(service.pluginIdentifier) created") - provider.tidePoolManager.addTidePoolService(service: service) - } - - func serviceOnboarding(didOnboardService service: Service) { - precondition(service.isOnboarded) - debug(.nightscout, "Service with identifier \(service.pluginIdentifier) onboarded") - } -} - -extension Settings.StateModel: CompletionDelegate { - func completionNotifyingDidComplete(_: CompletionNotifying) { - setupTidePool = false - provider.tidePoolManager.forceUploadData(device: fetchCgmManager.cgmManager?.cgmManagerStatus.device) - } -} diff --git a/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift b/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift index d03badf1d8..5444c15e86 100644 --- a/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift +++ b/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift @@ -1,6 +1,4 @@ import HealthKit -import LoopKit -import LoopKitUI import SwiftUI import Swinject @@ -66,11 +64,6 @@ extension Settings { Text("UI/UX Settings").navigationLink(to: .statisticsConfig, from: self) Text("Bolus Calculator").navigationLink(to: .bolusCalculatorConfig, from: self) Text("Nightscout").navigationLink(to: .nighscoutConfig, from: self) - - Text("TidePool") - .onTapGesture { - state.setupTidePool = true - } if HKHealthStore.isHealthDataAvailable() { Text("Apple Health").navigationLink(to: .healthkit, from: self) } @@ -185,27 +178,6 @@ extension Settings { ShareSheet(activityItems: state.logItems()) } .scrollContentBackground(.hidden).background(color) - .sheet(isPresented: $state.setupTidePool) { - if let serviceUIType = state.serviceUIType, - let pluginHost = state.provider.tidePoolManager.getTidePoolPluginHost() - { - if let serviceUI = state.provider.tidePoolManager.getTidePoolServiceUI() { - TidePoolSettingsView( - serviceUI: serviceUI, - serviceOnBoardDelegate: self.state, - serviceDelegate: self.state - ) - } else { - TidePoolSetupView( - serviceUIType: serviceUIType, - pluginHost: pluginHost, - serviceOnBoardDelegate: self.state, - serviceDelegate: self.state - ) - } - } - } - .scrollContentBackground(.hidden).background(color) .onAppear(perform: configureView) .navigationTitle("Settings") .toolbar { diff --git a/FreeAPS/Sources/Modules/Settings/View/TidePoolConfigView.swift b/FreeAPS/Sources/Modules/Settings/View/TidePoolConfigView.swift deleted file mode 100644 index fcef4b43a8..0000000000 --- a/FreeAPS/Sources/Modules/Settings/View/TidePoolConfigView.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Foundation -import LoopKit -import LoopKitUI -import SwiftUI - -struct TidePoolSetupView: UIViewControllerRepresentable { - let serviceUIType: ServiceUI.Type - let pluginHost: PluginHost - let serviceOnBoardDelegate: ServiceOnboardingDelegate - let serviceDelegate: CompletionDelegate - - func makeUIViewController(context _: UIViewControllerRepresentableContext) -> UIViewController { - let result = serviceUIType.setupViewController( - colorPalette: .default, - pluginHost: pluginHost - ) - switch result { - case let .createdAndOnboarded(serviceUI): - serviceOnBoardDelegate.serviceOnboarding(didCreateService: serviceUI) - serviceOnBoardDelegate.serviceOnboarding(didOnboardService: serviceUI) - return UIViewController() - case var .userInteractionRequired(setupViewControllerUI): - setupViewControllerUI.serviceOnboardingDelegate = serviceOnBoardDelegate - setupViewControllerUI.completionDelegate = serviceDelegate - return setupViewControllerUI - } - } - - func updateUIViewController(_: UIViewController, context _: UIViewControllerRepresentableContext) {} -} - -struct TidePoolSettingsView: UIViewControllerRepresentable { - let serviceUI: ServiceUI - let serviceOnBoardDelegate: ServiceOnboardingDelegate - let serviceDelegate: CompletionDelegate? - - func makeUIViewController(context _: UIViewControllerRepresentableContext) -> UIViewController { - var vc = serviceUI.settingsViewController(colorPalette: .default) - vc.completionDelegate = serviceDelegate - vc.serviceOnboardingDelegate = serviceOnBoardDelegate - return vc - } - - func updateUIViewController(_: UIViewController, context _: UIViewControllerRepresentableContext) {} -} diff --git a/FreeAPS/Sources/Router/Screen.swift b/FreeAPS/Sources/Router/Screen.swift index 4abe031fb6..e18666d85b 100644 --- a/FreeAPS/Sources/Router/Screen.swift +++ b/FreeAPS/Sources/Router/Screen.swift @@ -21,7 +21,6 @@ enum Screen: Identifiable, Hashable { case autotuneConfig case dataTable case cgm - case cgmDirect case healthkit case notificationsConfig case fpuConfig @@ -37,7 +36,6 @@ enum Screen: Identifiable, Hashable { case autoISFConf case B30Conf case KetoConfig - case calibrations case contactTrick var id: Int { String(reflecting: self).hashValue } @@ -83,9 +81,7 @@ extension Screen { case .dataTable: DataTable.RootView(resolver: resolver) case .cgm: - CGM.RootView(resolver: resolver, displayClose: false) - case .cgmDirect: - CGM.RootView(resolver: resolver, displayClose: true) + CGM.RootView(resolver: resolver) case .healthkit: AppleHealthKit.RootView(resolver: resolver) case .notificationsConfig: @@ -118,8 +114,6 @@ extension Screen { KetoConf.RootView(resolver: resolver) case .contactTrick: ContactTrick.RootView(resolver: resolver) - case .calibrations: - Calibrations.RootView(resolver: resolver) } } diff --git a/FreeAPS/Sources/Services/Network/TidepoolManager.swift b/FreeAPS/Sources/Services/Network/TidepoolManager.swift deleted file mode 100644 index 3cd85b3efb..0000000000 --- a/FreeAPS/Sources/Services/Network/TidepoolManager.swift +++ /dev/null @@ -1,426 +0,0 @@ -import Combine -import Foundation -import HealthKit -import LoopKit -import LoopKitUI -import Swinject - -protocol TidePoolManager { - func addTidePoolService(service: Service) - func getTidePoolServiceUI() -> ServiceUI? - func getTidePoolPluginHost() -> PluginHost? - func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID: String) - func deleteInsulin(at date: Date) -// func uploadStatus() - func uploadGlucose(device: HKDevice?) - func forceUploadData(device: HKDevice?) -// func uploadStatistics(dailystat: Statistics) -// func uploadPreferences(_ preferences: Preferences) -// func uploadProfileAndSettings(_: Bool) -} - -final class BaseTidePoolManager: TidePoolManager, Injectable { - @Injected() private var broadcaster: Broadcaster! - @Injected() private var pluginManager: PluginManager! - @Injected() private var glucoseStorage: GlucoseStorage! - @Injected() private var carbsStorage: CarbsStorage! - @Injected() private var storage: FileStorage! - @Injected() private var pumpHistoryStorage: PumpHistoryStorage! - - private let processQueue = DispatchQueue(label: "BaseNetworkManager.processQueue") - private var tidePoolService: RemoteDataService? { - didSet { - if let tidePoolService = tidePoolService { - rawTidePoolManager = tidePoolService.rawValue - } else { - rawTidePoolManager = nil - } - } - } - - @PersistedProperty(key: "TidePoolState") var rawTidePoolManager: Service.RawValue? - - init(resolver: Resolver) { - injectServices(resolver) - loadTidePoolManager() - subscribe() - } - - /// load the TidePool Remote Data Service if available - fileprivate func loadTidePoolManager() { - if let rawTidePoolManager = rawTidePoolManager { - tidePoolService = tidePoolServiceFromRaw(rawTidePoolManager) - tidePoolService?.serviceDelegate = self - tidePoolService?.stateDelegate = self - } - } - - /// allows to acces to tidePoolService as a simple ServiceUI - func getTidePoolServiceUI() -> ServiceUI? { - if let tidePoolService = self.tidePoolService { - return tidePoolService as! any ServiceUI as ServiceUI - } else { - return nil - } - } - - /// get the pluginHost of TidePool - func getTidePoolPluginHost() -> PluginHost? { - self as PluginHost - } - - func addTidePoolService(service: Service) { - tidePoolService = service as! any RemoteDataService as RemoteDataService - } - - /// load the TidePool Remote Data Service from raw storage - private func tidePoolServiceFromRaw(_ rawValue: [String: Any]) -> RemoteDataService? { - guard let rawState = rawValue["state"] as? Service.RawStateValue, - let serviceType = pluginManager.getServiceTypeByIdentifier("TidepoolService") - else { - return nil - } - if let service = serviceType.init(rawState: rawState) { - return service as! any RemoteDataService as RemoteDataService - } else { return nil } - } - - private func subscribe() { - broadcaster.register(PumpHistoryObserver.self, observer: self) - broadcaster.register(CarbsObserver.self, observer: self) - broadcaster.register(TempTargetsObserver.self, observer: self) - } - - func sourceInfo() -> [String: Any]? { - nil - } - - func uploadCarbs() { - let carbs: [CarbsEntry] = carbsStorage.recent() - - guard !carbs.isEmpty, let tidePoolService = self.tidePoolService else { return } - - processQueue.async { - carbs.chunks(ofCount: tidePoolService.carbDataLimit ?? 100).forEach { chunk in - - let syncCarb: [SyncCarbObject] = Array(chunk).map { - $0.convertSyncCarb() - } - tidePoolService.uploadCarbData(created: syncCarb, updated: [], deleted: []) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))") - case .success: - debug(.nightscout, "Success synchronizing carbs data:") - } - } - } - } - } - - func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID _: String) { - guard let tidePoolService = self.tidePoolService else { return } - - processQueue.async { - var carbsToDelete: [CarbsEntry] = [] - let allValues = self.storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self) ?? [] - - if let isFPU = isFPU, isFPU { - guard let fpuID = fpuID else { return } - carbsToDelete = allValues.filter { $0.fpuID == fpuID }.removeDublicates() - } else { - carbsToDelete = allValues.filter { $0.createdAt == date }.removeDublicates() - } - - let syncCarb = carbsToDelete.map { d in - d.convertSyncCarb(operation: .delete) - } - - tidePoolService.uploadCarbData(created: [], updated: [], deleted: syncCarb) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))") - case .success: - debug(.nightscout, "Success synchronizing carbs data:") - } - } - } - } - - func deleteInsulin(at d: Date) { - let allValues = storage.retrieve(OpenAPS.Monitor.pumpHistory, as: [PumpHistoryEvent].self) ?? [] - - guard !allValues.isEmpty, let tidePoolService = self.tidePoolService else { return } - - var doseDataToDelete: [DoseEntry] = [] - - guard let entry = allValues.first(where: { $0.timestamp == d }) else { - return - } - doseDataToDelete - .append(DoseEntry( - type: .bolus, - startDate: entry.timestamp, - value: Double(entry.amount!), - unit: .units, - syncIdentifier: entry.id - )) - - processQueue.async { - tidePoolService.uploadDoseData(created: [], deleted: doseDataToDelete) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing Dose delete data: \(String(describing: error))") - case .success: - debug(.nightscout, "Success synchronizing Dose delete data:") - } - } - } - } - - func uploadDose() { - let events = pumpHistoryStorage.recent() - guard !events.isEmpty, let tidePoolService = self.tidePoolService else { return } - - let eventsBasal = events.filter { $0.type == .tempBasal || $0.type == .tempBasalDuration } - .sorted { $0.timestamp < $1.timestamp } - - let doseDataBasal: [DoseEntry] = eventsBasal.reduce([]) { result, event in - var result = result - switch event.type { - case .tempBasal: - // update the previous tempBasal with endtime = starttime of the last event - if let last: DoseEntry = result.popLast() { - let value = max( - 0, - Double(event.timestamp.timeIntervalSince1970 - last.startDate.timeIntervalSince1970) / 3600 - ) * - (last.scheduledBasalRate?.doubleValue(for: .internationalUnitsPerHour) ?? 0.0) - result.append(DoseEntry( - type: .tempBasal, - startDate: last.startDate, - endDate: event.timestamp, - value: value, - unit: last.unit, - deliveredUnits: value, - syncIdentifier: last.syncIdentifier, - // scheduledBasalRate: last.scheduledBasalRate, - insulinType: last.insulinType, - automatic: last.automatic, - manuallyEntered: last.manuallyEntered - )) - } - result.append(DoseEntry( - type: .tempBasal, - startDate: event.timestamp, - value: 0.0, - unit: .unitsPerHour, - syncIdentifier: event.id, - scheduledBasalRate: HKQuantity(unit: .internationalUnitsPerHour, doubleValue: Double(event.rate!)), - insulinType: nil, - automatic: true, - manuallyEntered: false, - isMutable: true - )) - case .tempBasalDuration: - if let last: DoseEntry = result.popLast(), - last.type == .tempBasal, - last.startDate == event.timestamp - { - let durationMin = event.durationMin ?? 0 - // result.append(last) - let value = (Double(durationMin) / 60.0) * - (last.scheduledBasalRate?.doubleValue(for: .internationalUnitsPerHour) ?? 0.0) - result.append(DoseEntry( - type: .tempBasal, - startDate: last.startDate, - endDate: Calendar.current.date(byAdding: .minute, value: durationMin, to: last.startDate) ?? last - .startDate, - value: value, - unit: last.unit, - deliveredUnits: value, - syncIdentifier: last.syncIdentifier, - scheduledBasalRate: last.scheduledBasalRate, - insulinType: last.insulinType, - automatic: last.automatic, - manuallyEntered: last.manuallyEntered - )) - } - default: break - } - return result - } - - let boluses: [DoseEntry] = events.compactMap { event -> DoseEntry? in - switch event.type { - case .bolus: - return DoseEntry( - type: .bolus, - startDate: event.timestamp, - endDate: event.timestamp, - value: Double(event.amount!), - unit: .units, - deliveredUnits: nil, - syncIdentifier: event.id, - scheduledBasalRate: nil, - insulinType: nil, - automatic: true, - manuallyEntered: false - ) - default: return nil - } - } - - let pumpEvents: [PersistedPumpEvent] = events.compactMap { event -> PersistedPumpEvent? in - if let pumpEventType = event.type.mapEventTypeToPumpEventType() { - let dose: DoseEntry? = switch pumpEventType { - case .suspend: - DoseEntry(suspendDate: event.timestamp, automatic: true) - case .resume: - DoseEntry(resumeDate: event.timestamp, automatic: true) - default: - nil - } - - return PersistedPumpEvent( - date: event.timestamp, - persistedDate: event.timestamp, - dose: dose, - isUploaded: true, - objectIDURL: URL(string: "x-coredata:///PumpEvent/\(event.id)")!, - raw: event.id.data(using: .utf8), - title: event.note, - type: pumpEventType - ) - } else { - return nil - } - } - - processQueue.async { - tidePoolService.uploadDoseData(created: doseDataBasal + boluses, deleted: []) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing Dose data: \(String(describing: error))") - case .success: - debug(.nightscout, "Success synchronizing Dose data:") - } - } - - tidePoolService.uploadPumpEventData(pumpEvents) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing Pump Event data: \(String(describing: error))") - case .success: - debug(.nightscout, "Success synchronizing Pump Event data:") - } - } - } - } - - func uploadGlucose(device: HKDevice?) { - let glucose: [BloodGlucose] = glucoseStorage.recent() - - guard !glucose.isEmpty, let tidePoolService = self.tidePoolService else { return } - - let glucoseWithoutCorrectID = glucose.filter { UUID(uuidString: $0._id) != nil } - - processQueue.async { - glucoseWithoutCorrectID.chunks(ofCount: tidePoolService.glucoseDataLimit ?? 100) - .forEach { chunk in - // all glucose attached with the current device ;-( - - let chunkStoreGlucose = Array(chunk).map { - $0.convertStoredGlucoseSample(device: device) - } - tidePoolService.uploadGlucoseData(chunkStoreGlucose) { result in - switch result { - case let .failure(error): - debug(.nightscout, "Error synchronizing glucose data: \(String(describing: error))") - // self.uploadFailed(key) - case .success: - debug(.nightscout, "Success synchronizing glucose data:") - } - } - } - } - } - - /// force to uploads all data in TidePool Service - func forceUploadData(device: HKDevice?) { - uploadDose() - uploadCarbs() - uploadGlucose(device: device) - } -} - -extension BaseTidePoolManager: PumpHistoryObserver { - func pumpHistoryDidUpdate(_: [PumpHistoryEvent]) { - uploadDose() - } -} - -extension BaseTidePoolManager: CarbsObserver { - func carbsDidUpdate(_: [CarbsEntry]) { - uploadCarbs() - } -} - -extension BaseTidePoolManager: TempTargetsObserver { - func tempTargetsDidUpdate(_: [TempTarget]) {} -} - -extension BaseTidePoolManager: ServiceDelegate { - var hostIdentifier: String { - "com.loopkit.Loop" // To check - } - - var hostVersion: String { - var semanticVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String - - while semanticVersion.split(separator: ".").count < 3 { - semanticVersion += ".0" - } - - semanticVersion += "+\(Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String)" - - return semanticVersion - } - - func issueAlert(_: LoopKit.Alert) {} - - func retractAlert(identifier _: LoopKit.Alert.Identifier) {} - - func enactRemoteOverride(name _: String, durationTime _: TimeInterval?, remoteAddress _: String) async throws {} - - func cancelRemoteOverride() async throws {} - - func deliverRemoteCarbs( - amountInGrams _: Double, - absorptionTime _: TimeInterval?, - foodType _: String?, - startDate _: Date? - ) async throws {} - - func deliverRemoteBolus(amountInUnits _: Double) async throws {} -} - -extension BaseTidePoolManager: StatefulPluggableDelegate { - func pluginDidUpdateState(_: LoopKit.StatefulPluggable) {} - - func pluginWantsDeletion(_: LoopKit.StatefulPluggable) { - tidePoolService = nil - } -} - -// Service extension for rawValue -extension Service { - typealias RawValue = [String: Any] - - var rawValue: RawValue { - [ - "serviceIdentifier": pluginIdentifier, - "state": rawState - ] - } -} diff --git a/FreeAPSTests/CalibrationsTests.swift b/FreeAPSTests/CalibrationsTests.swift deleted file mode 100644 index 97fcc89388..0000000000 --- a/FreeAPSTests/CalibrationsTests.swift +++ /dev/null @@ -1,55 +0,0 @@ -@testable import FreeAPS -import Swinject -import XCTest - -class CalibrationsTests: XCTestCase, Injectable { - let fileStorage = BaseFileStorage() - @Injected() var calibrationService: CalibrationService! - let resolver = FreeAPSApp().resolver - - override func setUp() { - injectServices(resolver) - } - - func testCreateSimpleCalibration() { - let calibration = Calibration(x: 100.0, y: 102.0) - calibrationService.addCalibration(calibration) - - XCTAssertTrue(calibrationService.calibrations.isNotEmpty) - - XCTAssertTrue(calibrationService.slope == 1) - - XCTAssertTrue(calibrationService.intercept == 2) - - XCTAssertTrue(calibrationService.calibrate(value: 104) == 106) - } - - func testCreateMultipleCalibration() { - let calibration = Calibration(x: 100.0, y: 120) - calibrationService.addCalibration(calibration) - - let calibration2 = Calibration(x: 120.0, y: 130.0) - calibrationService.addCalibration(calibration2) - - XCTAssertTrue(calibrationService.slope == 0.8) - - XCTAssertTrue(calibrationService.intercept == 37) - - XCTAssertTrue(calibrationService.calibrate(value: 80) == 101) - - calibrationService.removeLast() - - XCTAssertTrue(calibrationService.calibrations.count == 1) - - calibrationService.removeAllCalibrations() - XCTAssertTrue(calibrationService.calibrations.isEmpty) - } - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } -} diff --git a/FreeAPSTests/PluginManagerTests.swift b/FreeAPSTests/PluginManagerTests.swift deleted file mode 100644 index 7d82fb99e2..0000000000 --- a/FreeAPSTests/PluginManagerTests.swift +++ /dev/null @@ -1,71 +0,0 @@ -@testable import FreeAPS -import Swinject -import XCTest - -class PluginManagerTests: XCTestCase, Injectable { - let fileStorage = BaseFileStorage() - @Injected() var pluginManager: PluginManager! - let resolver = FreeAPSApp().resolver - - override func setUp() { - injectServices(resolver) - } - - func testCGMManagerLoad() { - let cgmLoopManagers = pluginManager.availableCGMManagers - XCTAssertNotNil(cgmLoopManagers) - XCTAssertTrue(!cgmLoopManagers.isEmpty) - if let cgmLoop = cgmLoopManagers.first { - let cgmLoopManager = pluginManager.getCGMManagerTypeByIdentifier(cgmLoop.identifier) - XCTAssertNotNil(cgmLoopManager) - } else { - XCTFail("Not found CGM loop manager") - } - /// try to load a Pump manager with a CGM identifier - if let cgmLoop = cgmLoopManagers.last { - let cgmLoopManager = pluginManager.getPumpManagerTypeByIdentifier(cgmLoop.identifier) - XCTAssertNil(cgmLoopManager) - } else { - XCTFail("Not found CGM loop manager") - } - } - - func testPumpManagerLoad() { - let pumpLoopManagers = pluginManager.availablePumpManagers - XCTAssertNotNil(pumpLoopManagers) - XCTAssertTrue(!pumpLoopManagers.isEmpty) - if let pumpLoop = pumpLoopManagers.first { - let pumpLoopManager = pluginManager.getPumpManagerTypeByIdentifier(pumpLoop.identifier) - XCTAssertNotNil(pumpLoopManager) - } else { - XCTFail("Not found pump loop manager") - } - /// try to load a CGM manager with a pump identifier - if let pumpLoop = pumpLoopManagers.last { - let pumpLoopManager = pluginManager.getCGMManagerTypeByIdentifier(pumpLoop.identifier) - XCTAssertNil(pumpLoopManager) - } else { - XCTFail("Not found pump loop manager") - } - } - - func testServiceManagerLoad() { - let serviceManagers = pluginManager.availableServices - XCTAssertNotNil(serviceManagers) - XCTAssertTrue(!serviceManagers.isEmpty) - if let serviceLoop = serviceManagers.first { - let serviceManager = pluginManager.getServiceTypeByIdentifier(serviceLoop.identifier) - XCTAssertNotNil(serviceManager) - } else { - XCTFail("Not found Service loop manager") - } - } - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } -} diff --git a/TidepoolService b/TidepoolService deleted file mode 160000 index f7d46701f2..0000000000 --- a/TidepoolService +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f7d46701f24356e8ff387087cb4f687268ae0f3d diff --git a/scripts/swiftformat.sh b/scripts/swiftformat.sh index 6780ebe96f..dc625331a0 100755 --- a/scripts/swiftformat.sh +++ b/scripts/swiftformat.sh @@ -97,4 +97,4 @@ trailingClosures \ --typeattributes same-line \ --varattributes same-line \ --wrapcollections before-first \ ---exclude Pods,Generated,R.generated.swift,fastlane/swift,Dependencies, LoopKit, LibreTransmitter,G7SensorKit,OmniKit, dexcom-share-client-swift,CGMBLEKit,RileyLinkKit,OmniBLE,MinimedKit,TidepoolService +--exclude Pods,Generated,R.generated.swift,fastlane/swift,Dependencies, LoopKit, LibreTransmitter,G7SensorKit,OmniKit, dexcom-share-client-swift,CGMBLEKit,RileyLinkKit,OmniBLE,MinimedKit