Просмотр исходного кода

Refactor to enable oref from CLI tools

This change does a small refactor to enable us to run oref functions
from the CLI. By running oref functions from a CLI we can do more
extensive testing on the algorithm by replaying recorded inputs.

Any CLI programs we write will need to import the Trio package as
@testable for now. If we want to change that later, we'll need to add
`public` annotations to key functions and data structures to be able
to access them.
Sam King 4 дней назад
Родитель
Сommit
71802b530d

+ 71 - 0
Package.swift

@@ -0,0 +1,71 @@
+// swift-tools-version:5.9
+import PackageDescription
+
+// Builds the oref algorithm as a standalone, macOS-capable module
+// so the algorithm test suite can run with `swift test`
+//
+// This is a "shadow" package: it compiles the *existing* files in
+// place rather than owning its own copy, so there is exactly one
+// copy of every source file and the Xcode app target keeps
+// compiling the same ones.
+//
+// Usage:
+//   swift test                            # whole algorithm suite
+//   swift test --filter IobGenerateTests  # one suite
+
+let algorithmModels = [
+    "Autosens",
+    "BGTargets",
+    "BasalProfileEntry",
+    "BloodGlucose",
+    "CarbRatios",
+    "CarbsEntry",
+    "Determination",
+    "IOBEntry",
+    "InsulinSensitivities",
+    "Override",
+    "Preferences",
+    "PumpHistoryEvent",
+    "PumpSettings",
+    "TDD",
+    "TempBasal",
+    "TempTarget",
+    "TrioCustomOrefVariables"
+].map { "Models/\($0).swift" }
+
+let algorithmHelpers = [
+    "ConvenienceExtensions",
+    "Decimal+Extensions",
+    "Formatters",
+    "JSON",
+    "Rounding",
+    "String+Extensions",
+    "TimeInterval+Convenience"
+].map { "Helpers/\($0).swift" }
+
+let package = Package(
+    name: "TrioAlgorithm",
+    defaultLocalization: "en",
+    platforms: [.iOS(.v17), .macOS(.v14)],
+    products: [
+        .library(name: "Trio", targets: ["Trio"])
+    ],
+    targets: [
+        .target(
+            name: "Trio",
+            path: "Trio/Sources",
+            sources: [
+                "APS/OpenAPSSwift",
+                "APS/Extensions/DecimalExtensions.swift"
+            ] + algorithmModels + algorithmHelpers,
+            swiftSettings: [.define("TRIO_ALGORITHM_PACKAGE")]
+        ),
+        .testTarget(
+            name: "OpenAPSSwiftTests",
+            dependencies: ["Trio"],
+            path: "TrioTests/OpenAPSSwiftTests",
+            resources: [.copy("json")],
+            swiftSettings: [.define("TRIO_ALGORITHM_PACKAGE")]
+        )
+    ]
+)

+ 39 - 27
Trio.xcodeproj/project.pbxproj

@@ -401,6 +401,7 @@
 		AD3D2CD42CD01B9EB8F26522 /* PumpConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF65DA88F972B56090AD6AC3 /* PumpConfigDataFlow.swift */; };
 		B015AFE32E500000000D7351 /* BolusSafetyValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B015AFE12E500000000D7351 /* BolusSafetyValidator.swift */; };
 		B015AFE52E500000000D7351 /* BolusSafetyValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B015AFE42E500000000D7351 /* BolusSafetyValidatorTests.swift */; };
+		B63C9D934FC54853BC4EF29A /* NightscoutUploadSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10E61A0885164081B57C357C /* NightscoutUploadSerializer.swift */; };
 		B6E925132EB3932A0076D719 /* OmnipodKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6E925122EB3932A0076D719 /* OmnipodKit.framework */; };
 		B6E925142EB3932A0076D719 /* OmnipodKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B6E925122EB3932A0076D719 /* OmnipodKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		B7C465E9472624D8A2BE2A6A /* (null) in Sources */ = {isa = PBXBuildFile; };
@@ -410,7 +411,6 @@
 		BD04ECCE2D29952A008C5FEB /* BolusProgressOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD04ECCD2D299522008C5FEB /* BolusProgressOverlay.swift */; };
 		BD0B2EF32C5998E600B3298F /* MealPresetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD0B2EF22C5998E600B3298F /* MealPresetView.swift */; };
 		BD10516D2DA986E1007C6D89 /* PulsingLogoAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD10516C2DA986DC007C6D89 /* PulsingLogoAnimation.swift */; };
-		BD136FAE2F6AC55F002217F9 /* NSFetchedResultsControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD136FAD2F6AC555002217F9 /* NSFetchedResultsControllerDelegate.swift */; };
 		BD1179202F4E22C100F90001 /* TrioAlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1179212F4E22C100F90001 /* TrioAlertManager.swift */; };
 		BD1179222F4E22C100F90001 /* TrioModalAlertScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1179232F4E22C100F90001 /* TrioModalAlertScheduler.swift */; };
 		BD1179242F4E22C100F90001 /* TrioUserNotificationAlertScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1179252F4E22C100F90001 /* TrioUserNotificationAlertScheduler.swift */; };
@@ -471,6 +471,7 @@
 		BD11C001000000000000C001 /* CGMSensorDisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD11C000000000000000C001 /* CGMSensorDisplayState.swift */; };
 		BD11C001000000000000C003 /* SensorLifecycleArcView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD11C000000000000000C003 /* SensorLifecycleArcView.swift */; };
 		BD11C001000000000000C004 /* SensorStatusTagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD11C000000000000000C004 /* SensorStatusTagView.swift */; };
+		BD136FAE2F6AC55F002217F9 /* NSFetchedResultsControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD136FAD2F6AC555002217F9 /* NSFetchedResultsControllerDelegate.swift */; };
 		BD1661312B82ADAB00256551 /* CustomProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1661302B82ADAB00256551 /* CustomProgressView.swift */; };
 		BD175EBE0000100000000001 /* HistoryDataFlow+Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD175EFE0000100000000001 /* HistoryDataFlow+Models.swift */; };
 		BD175EBE0000100000000002 /* HistoryDeletionTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD175EFE0000100000000002 /* HistoryDeletionTarget.swift */; };
@@ -540,7 +541,6 @@
 		BD8E6B212D9036CA00ABF8FA /* OnboardingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8E6B202D9036CA00ABF8FA /* OnboardingProvider.swift */; };
 		BD8E6B232D9036F700ABF8FA /* OnboardingDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8E6B222D9036F700ABF8FA /* OnboardingDataFlow.swift */; };
 		BD8FC0542D66186000B95AED /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8FC0532D66186000B95AED /* TestError.swift */; };
-		FB9012AE66284A92A6531037 /* NightscoutUploadSerializerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C39FF1EC12CF4B1EBB13BE26 /* NightscoutUploadSerializerTests.swift */; };
 		BD8FC0572D66188700B95AED /* PumpHistoryStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8FC0562D66188700B95AED /* PumpHistoryStorageTests.swift */; };
 		BD8FC0592D66189700B95AED /* TestAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8FC0582D66189700B95AED /* TestAssembly.swift */; };
 		BD8FC05B2D6618AF00B95AED /* DeterminationStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8FC05A2D6618AF00B95AED /* DeterminationStorageTests.swift */; };
@@ -588,6 +588,9 @@
 		BDFF7A892D25F97D0016C40C /* TrioWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFF7A852D25F97D0016C40C /* TrioWatchApp.swift */; };
 		BDFF7A8B2D25F97D0016C40C /* Unit Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFF7A8A2D25F97D0016C40C /* Unit Tests.swift */; };
 		BF1667ADE69E4B5B111CECAE /* ManualTempBasalProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680C4420C9A345D46D90D06C /* ManualTempBasalProvider.swift */; };
+		C1A0DE000000000000000000 /* BloodGlucose+LoopKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A0DE000000000000000001 /* BloodGlucose+LoopKit.swift */; };
+		C1A0DE000000000000000002 /* PumpHistoryEvent+LoopKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A0DE000000000000000003 /* PumpHistoryEvent+LoopKit.swift */; };
+		C1A0DE000000000000000004 /* CarbsEntry+LoopKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A0DE000000000000000005 /* CarbsEntry+LoopKit.swift */; };
 		C21FE1E72DA59C6B007D550B /* GlucoseDailyDistributionChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21FE1E62DA59C6B007D550B /* GlucoseDailyDistributionChart.swift */; };
 		C263D59F2E4267F400CBF08C /* NightscoutUploadGlucoseStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C263D59E2E4267F400CBF08C /* NightscoutUploadGlucoseStepView.swift */; };
 		C28DD7262DBA9A9E00EC02DD /* GlucosePercentileDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C28DD7252DBA9A9E00EC02DD /* GlucosePercentileDetailView.swift */; };
@@ -785,7 +788,6 @@
 		DD868FD82E381A54005D3308 /* APNSJWTClaims.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD868FD72E381A54005D3308 /* APNSJWTClaims.swift */; };
 		DD88C8E22C50420800F2D558 /* DefinitionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD88C8E12C50420800F2D558 /* DefinitionRow.swift */; };
 		DD906BF42EA6AA0100262772 /* NightscoutUploadPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD906BF32EA6AA0100262772 /* NightscoutUploadPipeline.swift */; };
-		B63C9D934FC54853BC4EF29A /* NightscoutUploadSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10E61A0885164081B57C357C /* NightscoutUploadSerializer.swift */; };
 		DD906BF62EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD906BF52EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift */; };
 		DD940BAA2CA7585D000830A5 /* GlucoseColorScheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */; };
 		DD940BAC2CA75889000830A5 /* DynamicGlucoseColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */; };
@@ -833,9 +835,9 @@
 		DDD7C8C22F4DB45400E5CF09 /* GlucoseStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD7C8C02F4DB45400E5CF09 /* GlucoseStored+CoreDataProperties.swift */; };
 		DDDD0FFB2F4E22C000F9C645 /* GlucoseSmoothingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD0FFA2F4E22C000F9C645 /* GlucoseSmoothingTests.swift */; };
 		DDDD0FFD2F4E22C000F9C645 /* GlucoseNativeConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD0FFC2F4E22C000F9C645 /* GlucoseNativeConversionTests.swift */; };
+		DDDD0FFF2F4E231B00F9C645 /* MockTDDStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD0FFE2F4E231B00F9C645 /* MockTDDStorage.swift */; };
 		DDDD10A12F4E22C000F9C645 /* CarbsNativeConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD10A02F4E22C000F9C645 /* CarbsNativeConversionTests.swift */; };
 		DDDD10B12F4E22C000F9C645 /* PumpHistoryNativeConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD10B02F4E22C000F9C645 /* PumpHistoryNativeConversionTests.swift */; };
-		DDDD0FFF2F4E231B00F9C645 /* MockTDDStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDD0FFE2F4E231B00F9C645 /* MockTDDStorage.swift */; };
 		DDE179522C910127003CDDB7 /* MealPresetStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179322C910127003CDDB7 /* MealPresetStored+CoreDataClass.swift */; };
 		DDE179532C910127003CDDB7 /* MealPresetStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179332C910127003CDDB7 /* MealPresetStored+CoreDataProperties.swift */; };
 		DDE179542C910127003CDDB7 /* LoopStatRecord+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179342C910127003CDDB7 /* LoopStatRecord+CoreDataClass.swift */; };
@@ -913,6 +915,7 @@
 		F90692D6274B9A450037068D /* HealthKitStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F90692D5274B9A450037068D /* HealthKitStateModel.swift */; };
 		FA630397F76B582C8D8681A7 /* BasalProfileEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42369F66CF91F30624C0B3A6 /* BasalProfileEditorProvider.swift */; };
 		FA6B58486AE2496F9F8589C6 /* QuickPickBolusesConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EEC5C2927FA4C5DA61A1A40 /* QuickPickBolusesConfigProvider.swift */; };
+		FB9012AE66284A92A6531037 /* NightscoutUploadSerializerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C39FF1EC12CF4B1EBB13BE26 /* NightscoutUploadSerializerTests.swift */; };
 		FE41E4D629463EE20047FD55 /* NightscoutPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE41E4D529463EE20047FD55 /* NightscoutPreferences.swift */; };
 		FE66D16B291F74F8005D6F77 /* Bundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE66D16A291F74F8005D6F77 /* Bundle+Extensions.swift */; };
 		FEFFA7A22929FE49007B8193 /* UIDevice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFFA7A12929FE49007B8193 /* UIDevice+Extensions.swift */; };
@@ -1028,6 +1031,7 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		10E61A0885164081B57C357C /* NightscoutUploadSerializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadSerializer.swift; sourceTree = "<group>"; };
 		110AEDE02C5193D100615CC9 /* BolusIntent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusIntent.swift; sourceTree = "<group>"; };
 		110AEDE12C5193D100615CC9 /* BolusIntentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusIntentRequest.swift; sourceTree = "<group>"; };
 		110AEDE52C51A0AE00615CC9 /* ShortcutsConfigView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsConfigView.swift; sourceTree = "<group>"; };
@@ -1424,7 +1428,6 @@
 		BD04ECCD2D299522008C5FEB /* BolusProgressOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusProgressOverlay.swift; sourceTree = "<group>"; };
 		BD0B2EF22C5998E600B3298F /* MealPresetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealPresetView.swift; sourceTree = "<group>"; };
 		BD10516C2DA986DC007C6D89 /* PulsingLogoAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PulsingLogoAnimation.swift; sourceTree = "<group>"; };
-		BD136FAD2F6AC555002217F9 /* NSFetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchedResultsControllerDelegate.swift; sourceTree = "<group>"; };
 		BD1179212F4E22C100F90001 /* TrioAlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioAlertManager.swift; sourceTree = "<group>"; };
 		BD1179232F4E22C100F90001 /* TrioModalAlertScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioModalAlertScheduler.swift; sourceTree = "<group>"; };
 		BD1179252F4E22C100F90001 /* TrioUserNotificationAlertScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioUserNotificationAlertScheduler.swift; sourceTree = "<group>"; };
@@ -1485,6 +1488,7 @@
 		BD11C000000000000000C001 /* CGMSensorDisplayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMSensorDisplayState.swift; sourceTree = "<group>"; };
 		BD11C000000000000000C003 /* SensorLifecycleArcView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorLifecycleArcView.swift; sourceTree = "<group>"; };
 		BD11C000000000000000C004 /* SensorStatusTagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorStatusTagView.swift; sourceTree = "<group>"; };
+		BD136FAD2F6AC555002217F9 /* NSFetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchedResultsControllerDelegate.swift; sourceTree = "<group>"; };
 		BD1661302B82ADAB00256551 /* CustomProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomProgressView.swift; sourceTree = "<group>"; };
 		BD175EFE0000100000000001 /* HistoryDataFlow+Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HistoryDataFlow+Models.swift"; sourceTree = "<group>"; };
 		BD175EFE0000100000000002 /* HistoryDeletionTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryDeletionTarget.swift; sourceTree = "<group>"; };
@@ -1549,7 +1553,6 @@
 		BD8E6B202D9036CA00ABF8FA /* OnboardingProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProvider.swift; sourceTree = "<group>"; };
 		BD8E6B222D9036F700ABF8FA /* OnboardingDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingDataFlow.swift; sourceTree = "<group>"; };
 		BD8FC0532D66186000B95AED /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
-		C39FF1EC12CF4B1EBB13BE26 /* NightscoutUploadSerializerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadSerializerTests.swift; sourceTree = "<group>"; };
 		BD8FC0562D66188700B95AED /* PumpHistoryStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpHistoryStorageTests.swift; sourceTree = "<group>"; };
 		BD8FC0582D66189700B95AED /* TestAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAssembly.swift; sourceTree = "<group>"; };
 		BD8FC05A2D6618AF00B95AED /* DeterminationStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeterminationStorageTests.swift; sourceTree = "<group>"; };
@@ -1602,6 +1605,9 @@
 		BDFF7A922D25F97D0016C40C /* TrioWatchAppExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioWatchAppExtension.swift; sourceTree = "<group>"; };
 		BF8BCB0C37DEB5EC377B9612 /* BasalProfileEditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorRootView.swift; sourceTree = "<group>"; };
 		C19984D62EFC0035A9E9644D /* TreatmentsProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TreatmentsProvider.swift; sourceTree = "<group>"; };
+		C1A0DE000000000000000001 /* BloodGlucose+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BloodGlucose+LoopKit.swift"; sourceTree = "<group>"; };
+		C1A0DE000000000000000003 /* PumpHistoryEvent+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PumpHistoryEvent+LoopKit.swift"; sourceTree = "<group>"; };
+		C1A0DE000000000000000005 /* CarbsEntry+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CarbsEntry+LoopKit.swift"; sourceTree = "<group>"; };
 		C21FE1E62DA59C6B007D550B /* GlucoseDailyDistributionChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseDailyDistributionChart.swift; sourceTree = "<group>"; };
 		C263D59E2E4267F400CBF08C /* NightscoutUploadGlucoseStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadGlucoseStepView.swift; sourceTree = "<group>"; };
 		C28DD7252DBA9A9E00EC02DD /* GlucosePercentileDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucosePercentileDetailView.swift; sourceTree = "<group>"; };
@@ -1616,6 +1622,7 @@
 		C2BA6B962F758E7500348E6A /* WatchNotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchNotificationHandler.swift; sourceTree = "<group>"; };
 		C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationIdentifiers.swift; sourceTree = "<group>"; };
 		C377490C77661D75E8C50649 /* ManualTempBasalRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ManualTempBasalRootView.swift; sourceTree = "<group>"; };
+		C39FF1EC12CF4B1EBB13BE26 /* NightscoutUploadSerializerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadSerializerTests.swift; sourceTree = "<group>"; };
 		C8D1A7CA8C10C4403D4BBFA7 /* TreatmentsDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TreatmentsDataFlow.swift; sourceTree = "<group>"; };
 		CA01000000000000000010C1 /* AlertCatalogVendor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertCatalogVendor.swift; sourceTree = "<group>"; };
 		CA01000000000000000010C3 /* AlertCatalogRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertCatalogRegistry.swift; sourceTree = "<group>"; };
@@ -1799,7 +1806,6 @@
 		DD868FD72E381A54005D3308 /* APNSJWTClaims.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNSJWTClaims.swift; sourceTree = "<group>"; };
 		DD88C8E12C50420800F2D558 /* DefinitionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefinitionRow.swift; sourceTree = "<group>"; };
 		DD906BF32EA6AA0100262772 /* NightscoutUploadPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadPipeline.swift; sourceTree = "<group>"; };
-		10E61A0885164081B57C357C /* NightscoutUploadSerializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadSerializer.swift; sourceTree = "<group>"; };
 		DD906BF52EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BaseNightscoutManager+Subscribers.swift"; sourceTree = "<group>"; };
 		DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseColorScheme.swift; sourceTree = "<group>"; };
 		DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicGlucoseColor.swift; sourceTree = "<group>"; };
@@ -1850,9 +1856,9 @@
 		DDD7C8C02F4DB45400E5CF09 /* GlucoseStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GlucoseStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDDD0FFA2F4E22C000F9C645 /* GlucoseSmoothingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseSmoothingTests.swift; sourceTree = "<group>"; };
 		DDDD0FFC2F4E22C000F9C645 /* GlucoseNativeConversionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseNativeConversionTests.swift; sourceTree = "<group>"; };
+		DDDD0FFE2F4E231B00F9C645 /* MockTDDStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTDDStorage.swift; sourceTree = "<group>"; };
 		DDDD10A02F4E22C000F9C645 /* CarbsNativeConversionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbsNativeConversionTests.swift; sourceTree = "<group>"; };
 		DDDD10B02F4E22C000F9C645 /* PumpHistoryNativeConversionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpHistoryNativeConversionTests.swift; sourceTree = "<group>"; };
-		DDDD0FFE2F4E231B00F9C645 /* MockTDDStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTDDStorage.swift; sourceTree = "<group>"; };
 		DDE179322C910127003CDDB7 /* MealPresetStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MealPresetStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		DDE179332C910127003CDDB7 /* MealPresetStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MealPresetStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE179342C910127003CDDB7 /* LoopStatRecord+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoopStatRecord+CoreDataClass.swift"; sourceTree = "<group>"; };
@@ -2741,36 +2747,56 @@
 			children = (
 				BD11795B2F4E22C100F90001 /* GlucoseAlerts */,
 				49C782A62F73D9870062B0DD /* AlertEntry.swift */,
-				3E62C7812F54CC1600433237 /* BolusDisplayThreshold.swift */,
 				388E5A5F25B6F2310019842D /* Autosens.swift */,
 				388358C725EEF6D200E024B2 /* BasalProfileEntry.swift */,
 				38D0B3B525EBE24900CB6E88 /* Battery.swift */,
 				382C134A25F14E3700715CE1 /* BGTargets.swift */,
-				3E705AFA2FF94FAB0007F96B /* BolusStatus.swift */,
 				3870FF4225EC13F40088248F /* BloodGlucose.swift */,
+				C1A0DE000000000000000001 /* BloodGlucose+LoopKit.swift */,
+				3E62C7812F54CC1600433237 /* BolusDisplayThreshold.swift */,
+				3E705AFA2FF94FAB0007F96B /* BolusStatus.swift */,
 				38A9260425F012D8009E3739 /* CarbRatios.swift */,
 				38D0B3D825EC07C400CB6E88 /* CarbsEntry.swift */,
+				C1A0DE000000000000000005 /* CarbsEntry+LoopKit.swift */,
+				19D4E4EA29FC6A9F00351451 /* Charts.swift */,
 				DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */,
+				DD9ECB692CA99F6C00AA7C45 /* CommandPayload.swift */,
 				E592A36F2CEEC01E009A472C /* ContactTrickEntry.swift */,
 				3811DF0125CA9FEA00A708ED /* Credentials.swift */,
+				19A910352A24D6D700C8951B /* DateFilter.swift */,
+				DD21FCB42C6952AD00AF2C25 /* DecimalPickerSettings.swift */,
+				583684072BD195A700070A60 /* Determination.swift */,
+				DDD6D4D22CDE90720029439A /* EstimatedA1cDisplayUnit.swift */,
 				DD3D60302F0377350021A33B /* ExportSetting.swift */,
+				DD6B7CB32C7B71F700B75029 /* ForecastDisplayType.swift */,
 				DD3078692D42F94000DE0490 /* GarminDevice.swift */,
 				49090A8C2E9FE8D200D0F5DB /* GarminWatchSettings.swift */,
 				DD4FFF322D458EE600B6CFF9 /* GarminWatchState.swift */,
 				DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */,
 				BD1179AD2F4E22C100F90001 /* GlucoseSourceKey.swift */,
 				E0D4F80427513ECF00BDF1FE /* HealthKitSample.swift */,
+				1967DFBD29D052C200759F30 /* Icons.swift */,
 				382C133625F13A1E00715CE1 /* InsulinSensitivities.swift */,
 				38887CCD25F5725200944304 /* IOBEntry.swift */,
+				BDF530D72B40F8AC002CAF43 /* LockScreenView.swift */,
+				193F6CDC2A512C8F001240FD /* Loops.swift */,
+				19012CDB291D2CB900FB8210 /* LoopStats.swift */,
 				DD68889C2C386E17006E3C44 /* NightscoutExercise.swift */,
+				FE41E4D529463EE20047FD55 /* NightscoutPreferences.swift */,
+				191F62672AD6B05A004D7911 /* NightscoutSettings.swift */,
 				385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */,
 				389442CA25F65F7100FA1F27 /* NightscoutTreatment.swift */,
+				C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */,
+				BDC2EA462C3045AD00E5BBD0 /* Override.swift */,
 				BD54A95A2D28087700F9C1EE /* OverridePresetWatch.swift */,
 				3895E4C525B9E00D00214B37 /* Preferences.swift */,
 				38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */,
+				C1A0DE000000000000000003 /* PumpHistoryEvent+LoopKit.swift */,
 				3883583325EEB38000E024B2 /* PumpSettings.swift */,
 				38E989DC25F5021400C0CED0 /* PumpStatus.swift */,
+				CC6C406D2ACDD69E009B8058 /* RawFetchedProfile.swift */,
 				38BF021C25E7E3AF00579895 /* Reservoir.swift */,
+				19B0EF2028F6D66200069496 /* Statistics.swift */,
 				3B2F77852D7E52ED005ED9FA /* TDD.swift */,
 				38A0364125ED069400FCBB52 /* TempBasal.swift */,
 				3871F39B25ED892B0013ECB5 /* TempTarget.swift */,
@@ -2783,23 +2809,6 @@
 				BD432CA02D2F4E3300D1EB79 /* WatchMessageKeys.swift */,
 				BDA25EFC2D261BF200035F34 /* WatchState.swift */,
 				DDFF204F2DB2C11900AB8A96 /* WatchStateSnapshot.swift */,
-				19B0EF2028F6D66200069496 /* Statistics.swift */,
-				19012CDB291D2CB900FB8210 /* LoopStats.swift */,
-				FE41E4D529463EE20047FD55 /* NightscoutPreferences.swift */,
-				191F62672AD6B05A004D7911 /* NightscoutSettings.swift */,
-				1967DFBD29D052C200759F30 /* Icons.swift */,
-				19D4E4EA29FC6A9F00351451 /* Charts.swift */,
-				19A910352A24D6D700C8951B /* DateFilter.swift */,
-				193F6CDC2A512C8F001240FD /* Loops.swift */,
-				CC6C406D2ACDD69E009B8058 /* RawFetchedProfile.swift */,
-				BDF530D72B40F8AC002CAF43 /* LockScreenView.swift */,
-				583684072BD195A700070A60 /* Determination.swift */,
-				BDC2EA462C3045AD00E5BBD0 /* Override.swift */,
-				DD21FCB42C6952AD00AF2C25 /* DecimalPickerSettings.swift */,
-				DD6B7CB32C7B71F700B75029 /* ForecastDisplayType.swift */,
-				DD9ECB692CA99F6C00AA7C45 /* CommandPayload.swift */,
-				DDD6D4D22CDE90720029439A /* EstimatedA1cDisplayUnit.swift */,
-				C2BA6B982F758E7600348E6A /* NotificationIdentifiers.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -4982,6 +4991,9 @@
 				DDF847E82C5DABA30049BB3B /* WatchConfigAppleWatchView.swift in Sources */,
 				3811DF1025CAAAE200A708ED /* APSManager.swift in Sources */,
 				3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */,
+				C1A0DE000000000000000000 /* BloodGlucose+LoopKit.swift in Sources */,
+				C1A0DE000000000000000002 /* PumpHistoryEvent+LoopKit.swift in Sources */,
+				C1A0DE000000000000000004 /* CarbsEntry+LoopKit.swift in Sources */,
 				DDBD53FC2DAA903100F940A6 /* OverviewStepView.swift in Sources */,
 				38A0364225ED069400FCBB52 /* TempBasal.swift in Sources */,
 				3811DE1725C9D40400A708ED /* Screen.swift in Sources */,

+ 0 - 4
Trio/Sources/APS/Extensions/DecimalExtensions.swift

@@ -1,10 +1,6 @@
 import Foundation
 
 extension Decimal {
-    func clamp(to pickerSetting: PickerSetting) -> Decimal {
-        max(min(self, pickerSetting.max), pickerSetting.min)
-    }
-
     /// Converts a `Double` to a `Decimal` using JSON style conversion
     init(algorithmValue value: Double) {
         self = Decimal(string: value.description) ?? Decimal(value)

+ 70 - 0
Trio/Sources/APS/OpenAPSSwift/AlgorithmLoggingShim.swift

@@ -0,0 +1,70 @@
+import Foundation
+
+// MARK: - Package-only logging shim
+
+//
+// This file exists solely for the `Trio` SPM target declared in the repo-root
+// `Package.swift`, which compiles the oref algorithm (plus its models) as a
+// standalone macOS-capable module so `swift test` can run the algorithm suite
+// without building the iOS app or booting a simulator.
+//
+
+#if TRIO_ALGORITHM_PACKAGE
+
+    /// Stands in for the app's `Logger` so `Logger.Category` resolves in the package.
+    enum Logger {
+        /// Mirrors `Logger.Category` in the app target.
+        enum Category: String {
+            case `default`
+            case service
+            case businessLogic
+            case openAPS
+            case deviceManager
+            case apsManager
+            case nightscout
+            case remoteControl
+            case bolusState
+            case watchManager
+            case coreData
+            case storage
+            case telemetry
+        }
+    }
+
+    /// Set by a test to capture algorithm log output; defaults to discarding it.
+    nonisolated(unsafe) var algorithmLogSink: ((Logger.Category, String) -> Void)?
+
+    func debug(
+        _ category: Logger.Category,
+        _ message: @autoclosure () -> String,
+        printToConsole _: Bool = true,
+        file _: String = #file,
+        function _: String = #function,
+        line _: UInt = #line
+    ) {
+        algorithmLogSink?(category, message())
+    }
+
+    func info(
+        _ category: Logger.Category,
+        _ message: String,
+        file _: String = #file,
+        function _: String = #function,
+        line _: UInt = #line
+    ) {
+        algorithmLogSink?(category, message)
+    }
+
+    func warning(
+        _ category: Logger.Category,
+        _ message: String,
+        description _: String? = nil,
+        error _: Swift.Error? = nil,
+        file _: String = #file,
+        function _: String = #function,
+        line _: UInt = #line
+    ) {
+        algorithmLogSink?(category, message)
+    }
+
+#endif

+ 21 - 0
Trio/Sources/APS/OpenAPSSwift/Extensions/Decimal+rounding.swift

@@ -44,4 +44,25 @@ extension Decimal {
             return self
         }
     }
+
+    /// Rounds a decimal to specified number of places
+    /// - Parameter places: Number of decimal places
+    /// - Returns: Rounded decimal
+    func rounded(toPlaces places: Int) -> Decimal {
+        var value = self
+        var result = Decimal()
+        NSDecimalRound(&result, &value, places, .plain)
+        return result
+    }
+
+    /// Truncates the `Decimal` to the specified number of decimal places without rounding.
+    ///
+    /// - Parameter places: The number of decimal places to retain.
+    /// - Returns: A `Decimal` truncated to the specified precision.
+    func truncated(toPlaces places: Int) -> Decimal {
+        var original = self
+        var result = Decimal()
+        NSDecimalRound(&result, &original, places, .down)
+        return result
+    }
 }

+ 0 - 24
Trio/Sources/APS/Storage/TDDStorage.swift

@@ -662,30 +662,6 @@ final class BaseTDDStorage: TDDStorage, Injectable {
     }
 }
 
-/// Extension for rounding Decimal numbers
-extension Decimal {
-    /// Rounds a decimal to specified number of places
-    /// - Parameter places: Number of decimal places
-    /// - Returns: Rounded decimal
-    func rounded(toPlaces places: Int) -> Decimal {
-        var value = self
-        var result = Decimal()
-        NSDecimalRound(&result, &value, places, .plain)
-        return result
-    }
-
-    /// Truncates the `Decimal` to the specified number of decimal places without rounding.
-    ///
-    /// - Parameter places: The number of decimal places to retain.
-    /// - Returns: A `Decimal` truncated to the specified precision.
-    func truncated(toPlaces places: Int) -> Decimal {
-        var original = self
-        var result = Decimal()
-        NSDecimalRound(&result, &original, places, .down)
-        return result
-    }
-}
-
 /// Finds the basal rate at the specified minute offset using binary search
 /// - Parameters:
 ///   - totalMinutes: minute offset into a 24 hour day

+ 2 - 1
Trio/Sources/Helpers/ConvenienceExtensions.swift

@@ -1,4 +1,5 @@
-import UIKit
+import CoreGraphics
+import Foundation
 
 protocol Occupiable {
     var isEmpty: Bool { get }

+ 0 - 1
Trio/Sources/Helpers/Formatters.swift

@@ -1,5 +1,4 @@
 import Foundation
-import HealthKit
 
 enum Formatters {
     static func percent(for number: Double) -> String {

+ 20 - 0
Trio/Sources/Models/BloodGlucose+LoopKit.swift

@@ -0,0 +1,20 @@
+import Foundation
+import HealthKit
+import LoopKit
+
+// LoopKit/HealthKit adapter for `BloodGlucose`.
+//
+// Kept out of `BloodGlucose.swift` so that the model itself stays Foundation-only and can be
+// compiled by the algorithm package (see the repo-root `Package.swift`). Consumed by
+// `GlucoseStorage`.
+extension BloodGlucose {
+    func convertStoredGlucoseSample(isManualGlucose: Bool) -> StoredGlucoseSample {
+        StoredGlucoseSample(
+            syncIdentifier: id,
+            startDate: dateString.date,
+            quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose!)),
+            wasUserEntered: isManualGlucose,
+            device: HKDevice.local()
+        )
+    }
+}

+ 0 - 14
Trio/Sources/Models/BloodGlucose.swift

@@ -1,6 +1,4 @@
 import Foundation
-import HealthKit
-import LoopKit
 
 struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
     enum Direction: String, JSON {
@@ -276,15 +274,3 @@ extension NumberFormatter {
         return formatter
     }()
 }
-
-extension BloodGlucose {
-    func convertStoredGlucoseSample(isManualGlucose: Bool) -> StoredGlucoseSample {
-        StoredGlucoseSample(
-            syncIdentifier: id,
-            startDate: dateString.date,
-            quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose!)),
-            wasUserEntered: isManualGlucose,
-            device: HKDevice.local()
-        )
-    }
-}

+ 29 - 0
Trio/Sources/Models/CarbsEntry+LoopKit.swift

@@ -0,0 +1,29 @@
+import Foundation
+import LoopKit
+
+// LoopKit adapter for `CarbsEntry`.
+//
+// Kept out of `CarbsEntry.swift` so that the model itself stays Foundation-only and can be
+// compiled by the algorithm package (see the repo-root `Package.swift`). Consumed by
+// `TidepoolManager`.
+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 ?? "Trio",
+            syncIdentifier: id,
+            syncVersion: nil,
+            userCreatedDate: nil,
+            userUpdatedDate: nil,
+            userDeletedDate: nil,
+            operation: operation,
+            addedDate: nil,
+            supercededDate: nil
+        )
+    }
+}

+ 0 - 23
Trio/Sources/Models/CarbsEntry.swift

@@ -1,5 +1,4 @@
 import Foundation
-import LoopKit
 
 struct CarbsEntry: JSON, Equatable, Hashable, Identifiable {
     let id: String?
@@ -39,25 +38,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 ?? "Trio",
-            syncIdentifier: id,
-            syncVersion: nil,
-            userCreatedDate: nil,
-            userUpdatedDate: nil,
-            userDeletedDate: nil,
-            operation: operation,
-            addedDate: nil,
-            supercededDate: nil
-        )
-    }
-}

+ 10 - 0
Trio/Sources/Models/DecimalPickerSettings.swift

@@ -143,6 +143,16 @@ struct DecimalPickerSettings {
     )
 }
 
+extension Decimal {
+    /// Clamps the value into the range a picker allows.
+    ///
+    /// Lives here rather than with the general `Decimal` helpers so that those stay free of
+    /// UI-layer types — `PickerSetting` is declared just below.
+    func clamp(to pickerSetting: PickerSetting) -> Decimal {
+        max(min(self, pickerSetting.max), pickerSetting.min)
+    }
+}
+
 struct PickerSetting {
     var value: Decimal
     var step: Decimal

+ 0 - 1
Trio/Sources/Models/Determination.swift

@@ -63,7 +63,6 @@ extension Determination {
         case isf = "ISF"
         case current_target
         case tdd = "TDD"
-        case insulinForManualBolus
         case minDelta
         case expectedDelta
         case minGuardBG

+ 33 - 0
Trio/Sources/Models/PumpHistoryEvent+LoopKit.swift

@@ -0,0 +1,33 @@
+import Foundation
+import LoopKit
+
+// LoopKit adapter for `EventType`.
+//
+// Kept out of `PumpHistoryEvent.swift` so that the model itself stays Foundation-only and can be
+// compiled by the algorithm package (see the repo-root `Package.swift`). Consumed by
+// `TidepoolManager`.
+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
+        }
+    }
+}

+ 0 - 27
Trio/Sources/Models/PumpHistoryEvent.swift

@@ -1,5 +1,4 @@
 import Foundation
-import LoopKit
 
 struct PumpHistoryEvent: JSON, Equatable, Identifiable {
     let id: String
@@ -102,29 +101,3 @@ extension PumpHistoryEvent {
         case isExternalInsulin
     }
 }
-
-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
-        }
-    }
-}

+ 2 - 4
TrioTests/OpenAPSSwiftTests/ProfileJavascriptTests.swift

@@ -12,8 +12,7 @@ struct ProfileGeneratorTests {
         Preferences,
         CarbRatios,
         [TempTarget],
-        String,
-        TrioSettings
+        String
     ) {
         let pumpSettings = PumpSettings(
             insulinActionCurve: 10,
@@ -52,9 +51,8 @@ struct ProfileGeneratorTests {
 
         let tempTargets: [TempTarget] = []
         let model = "523"
-        let trioSettings = TrioSettings()
 
-        return (pumpSettings, bgTargets, basalProfile, isf, preferences, carbRatios, tempTargets, model, trioSettings)
+        return (pumpSettings, bgTargets, basalProfile, isf, preferences, carbRatios, tempTargets, model)
     }
 
     @Test("Basic profile generation should create profile with correct values") func testBasicProfileGeneration() throws {