Browse Source

[Part 6 of 6] Remove OpenAPSSwift.swift and use native arguments

This commit is the last part of our removal of the JSON conversion we
used to do when we ran the oref algorithm using Javascript. In this
commit, we remove the OpenAPSSwift file and just call the underlying
algorithm functions directly from OpenAPS.

One change in functionality is that we expose raw DeterminationError
messages instead of catching them and converting them to APSError
exceptions with a generic "No determination error" error
message. These exception messages will be user visible when they
happen.
Sam King 1 day ago
parent
commit
991dff1b15

+ 0 - 8
Trio.xcodeproj/project.pbxproj

@@ -256,7 +256,6 @@
 		3B506FD92E635304000740B9 /* IOBService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B506FD82E635304000740B9 /* IOBService.swift */; };
 		3B56079E2ECD62A800C723C1 /* DeletedGlucoseStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B56079D2ECD62A800C723C1 /* DeletedGlucoseStored+CoreDataClass.swift */; };
 		3B5607A02ECD62AC00C723C1 /* DeletedGlucoseStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B56079F2ECD62AC00C723C1 /* DeletedGlucoseStored+CoreDataProperties.swift */; };
-		3B5CD1EC2D4912A600CE213C /* OpenAPSSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5CD1E92D4912A600CE213C /* OpenAPSSwift.swift */; };
 		3B5CD1ED2D4912A600CE213C /* JSONBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5CD1EA2D4912A600CE213C /* JSONBridge.swift */; };
 		3B5CD2982D4AEA3C00CE213C /* Carbs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5CD2922D4AEA3C00CE213C /* Carbs.swift */; };
 		3B5CD2992D4AEA3C00CE213C /* Isf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5CD2932D4AEA3C00CE213C /* Isf.swift */; };
@@ -300,7 +299,6 @@
 		3BD9687F2D8DDD8800899469 /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 3BD9687E2D8DDD8800899469 /* CryptoSwift */; };
 		3BE2F1E82E030E2F009E2900 /* MealCobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BE2F1E72E030E2F009E2900 /* MealCobTests.swift */; };
 		3BE2F1EA2E031951009E2900 /* MealCobBucketingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BE2F1E92E031951009E2900 /* MealCobBucketingTests.swift */; };
-		3BEA3AE02D58F79700A67A1D /* OrefFunctionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEA3ADE2D58F79700A67A1D /* OrefFunctionResult.swift */; };
 		3BEDC9932EEB27B600AC6492 /* IobConsecutiveEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEDC9922EEB27B600AC6492 /* IobConsecutiveEventsTests.swift */; };
 		3BEF6AB12D9731660076089D /* MealHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB02D9731530076089D /* MealHistoryTests.swift */; };
 		3BEF6AB32D97316F0076089D /* MealTotalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB22D97316A0076089D /* MealTotalTests.swift */; };
@@ -1270,7 +1268,6 @@
 		3B506FD82E635304000740B9 /* IOBService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOBService.swift; sourceTree = "<group>"; };
 		3B56079D2ECD62A800C723C1 /* DeletedGlucoseStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeletedGlucoseStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		3B56079F2ECD62AC00C723C1 /* DeletedGlucoseStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeletedGlucoseStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
-		3B5CD1E92D4912A600CE213C /* OpenAPSSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenAPSSwift.swift; sourceTree = "<group>"; };
 		3B5CD1EA2D4912A600CE213C /* JSONBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONBridge.swift; sourceTree = "<group>"; };
 		3B5CD2912D4AEA3C00CE213C /* Basal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Basal.swift; sourceTree = "<group>"; };
 		3B5CD2922D4AEA3C00CE213C /* Carbs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Carbs.swift; sourceTree = "<group>"; };
@@ -1313,7 +1310,6 @@
 		3BDEA2DC60EDE0A3CA54DC73 /* TargetsEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorProvider.swift; sourceTree = "<group>"; };
 		3BE2F1E72E030E2F009E2900 /* MealCobTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealCobTests.swift; sourceTree = "<group>"; };
 		3BE2F1E92E031951009E2900 /* MealCobBucketingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealCobBucketingTests.swift; sourceTree = "<group>"; };
-		3BEA3ADE2D58F79700A67A1D /* OrefFunctionResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrefFunctionResult.swift; sourceTree = "<group>"; };
 		3BEDC9922EEB27B600AC6492 /* IobConsecutiveEventsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IobConsecutiveEventsTests.swift; sourceTree = "<group>"; };
 		3BEF6AB02D9731530076089D /* MealHistoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealHistoryTests.swift; sourceTree = "<group>"; };
 		3BEF6AB22D97316A0076089D /* MealTotalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealTotalTests.swift; sourceTree = "<group>"; };
@@ -3079,8 +3075,6 @@
 				3B5CD2B22D4AEA6600CE213C /* Models */,
 				3B5CD2972D4AEA3C00CE213C /* Profile */,
 				3B5CD2A02D4AEA5100CE213C /* Utils */,
-				3B5CD1E92D4912A600CE213C /* OpenAPSSwift.swift */,
-				3BEA3ADE2D58F79700A67A1D /* OrefFunctionResult.swift */,
 				3B5CD1EA2D4912A600CE213C /* JSONBridge.swift */,
 			);
 			path = OpenAPSSwift;
@@ -5143,7 +5137,6 @@
 				582DF97B2C8CE209001F516D /* CarbView.swift in Sources */,
 				DD940BAA2CA7585D000830A5 /* GlucoseColorScheme.swift in Sources */,
 				3811DE2225C9D48300A708ED /* MainProvider.swift in Sources */,
-				3BEA3AE02D58F79700A67A1D /* OrefFunctionResult.swift in Sources */,
 				BD47FD1B2D88AB4F0043966B /* OnboardingStateModel.swift in Sources */,
 				3811DE0C25C9D32F00A708ED /* BaseProvider.swift in Sources */,
 				CE95BF5A2BA62E4A00DC3DE3 /* PluginSource.swift in Sources */,
@@ -5434,7 +5427,6 @@
 				C29835B02E2AA3F30068C5BB /* NightscoutUploadStepView.swift in Sources */,
 				58D08B3A2C8DFECD00AA37D3 /* TempTargets.swift in Sources */,
 				38E98A2325F52C9300C0CED0 /* Signpost.swift in Sources */,
-				3B5CD1EC2D4912A600CE213C /* OpenAPSSwift.swift in Sources */,
 				3B5CD1ED2D4912A600CE213C /* JSONBridge.swift in Sources */,
 				CE7CA3542A064973004BE681 /* TempPresetsIntentRequest.swift in Sources */,
 				58A3D5442C96DE11003F90FC /* TempTargetStored+Helper.swift in Sources */,

+ 115 - 90
Trio/Sources/APS/OpenAPS/OpenAPS.swift

@@ -245,9 +245,6 @@ final class OpenAPS {
 
         let context = newContext("determineBasal")
 
-        // temp_basal
-        let tempBasal = currentTemp.rawJSON
-
         // Perform asynchronous calls in parallel
         async let pumpHistoryObjectIDs = fetchPumpHistoryObjectIDs(on: context) ?? []
         async let carbsFetch = carbsStorage.getCarbsForAlgorithm(
@@ -274,11 +271,11 @@ final class OpenAPS {
             pumpHistory,
             carbs,
             glucose,
-            trioCustomOrefVariables,
-            profile,
-            basalProfile,
-            autosens,
-            reservoir,
+            rawTrioCustomOrefVariables,
+            rawProfile,
+            rawBasalProfile,
+            rawAutosens,
+            rawReservoir,
             hasSufficientTdd
         ) = await (
             try parsePumpHistory(on: context, await pumpHistoryObjectIDs, simulatedBolusAmount: simulatedBolusAmount),
@@ -292,6 +289,16 @@ final class OpenAPS {
             try hasSufficientTddForDynamic
         )
 
+        // Decode the JSON-at-rest inputs into native models at the call boundary.
+        // The bundled-defaults fallback still happens in loadFileFromStorageAsync
+        // above, so decoding here preserves the same behavior it previously had
+        // inside OpenAPSSwift.
+        let profile = try JSONBridge.profile(from: rawProfile)
+        let basalProfile = try JSONBridge.basalProfile(from: rawBasalProfile)
+        let autosens = try JSONBridge.autosens(from: rawAutosens.isEmpty ? .null : rawAutosens)
+        let reservoir = Decimal(string: rawReservoir) ?? 100
+        let trioCustomOrefVariables = try JSONBridge.trioCustomOrefVariables(from: rawTrioCustomOrefVariables)
+
         // Meal calculation
         let meal = try self.meal(
             pumphistory: pumpHistory,
@@ -307,7 +314,7 @@ final class OpenAPS {
             pumphistory: pumpHistory,
             profile: profile,
             clock: clock,
-            autosens: autosens.isEmpty ? .null : autosens
+            autosens: autosens
         )
 
         // TODO: refactor this to core data
@@ -324,21 +331,20 @@ final class OpenAPS {
         // Determine basal
         let orefDetermination = try determineBasal(
             glucose: glucose,
-            currentTemp: tempBasal,
+            currentTemp: currentTemp,
             iob: iob,
             profile: profile,
-            autosens: autosens.isEmpty ? .null : autosens,
+            autosens: autosens,
             meal: meal,
             microBolusAllowed: true,
             reservoir: reservoir,
             preferences: preferences,
-            basalProfile: basalProfile,
             trioCustomOrefVariables: trioCustomOrefVariables
         )
 
-        debug(.openAPS, "\(simulation ? "[SIMULATION]" : "") OREF DETERMINATION: \(orefDetermination)")
+        debug(.openAPS, "\(simulation ? "[SIMULATION]" : "") OREF DETERMINATION: \(String(describing: orefDetermination))")
 
-        if var determination = Determination(from: orefDetermination), let deliverAt = determination.deliverAt {
+        if var determination = orefDetermination, let deliverAt = determination.deliverAt {
             // set both timestamp and deliverAt to the SAME date; this will be updated for timestamp once it is enacted
             // AAPS does it the same way! we'll follow their example!
             determination.timestamp = deliverAt
@@ -352,7 +358,7 @@ final class OpenAPS {
         } else {
             debug(
                 .openAPS,
-                "\(DebuggingIdentifiers.failed) No determination data. orefDetermination: \(orefDetermination), Determination(from: orefDetermination): \(String(describing: Determination(from: orefDetermination))), deliverAt: \(String(describing: Determination(from: orefDetermination)?.deliverAt))"
+                "\(DebuggingIdentifiers.failed) No determination data. determination: \(String(describing: orefDetermination)), deliverAt: \(String(describing: orefDetermination?.deliverAt))"
             )
             throw APSError.apsError(message: "No determination data.")
         }
@@ -444,7 +450,7 @@ final class OpenAPS {
         async let getTempTargets = loadFileFromStorageAsync(name: Settings.tempTargets)
 
         // Await the results of asynchronous tasks
-        let (pumpHistory, carbs, glucose, profile, basalProfile, tempTargets) = await (
+        let (pumpHistory, carbs, glucose, rawProfile, rawBasalProfile, rawTempTargets) = await (
             try parsePumpHistory(on: context, await pumpHistoryObjectIDs),
             try carbsFetch,
             try glucoseFetch,
@@ -453,25 +459,27 @@ final class OpenAPS {
             getTempTargets
         )
 
+        // Decode the JSON-at-rest inputs into native models at the call boundary.
+        let profile = try JSONBridge.profile(from: rawProfile)
+        let basalProfile = try JSONBridge.basalProfile(from: rawBasalProfile)
+        let tempTargets = try JSONBridge.tempTargets(from: rawTempTargets)
+
         // Autosense
-        let autosenseResult = try autosense(
+        var autosens = try autosense(
             glucose: glucose,
             pumpHistory: pumpHistory,
-            basalprofile: basalProfile,
+            basalProfile: basalProfile,
             profile: profile,
             carbs: carbs,
-            temptargets: tempTargets
+            tempTargets: tempTargets,
+            clock: Date()
         )
 
-        debug(.openAPS, "AUTOSENS: \(autosenseResult)")
-        if var autosens = Autosens(from: autosenseResult) {
-            autosens.timestamp = Date()
-            await storage.saveAsync(autosens, as: Settings.autosense)
+        debug(.openAPS, "AUTOSENS: \(autosens)")
+        autosens.timestamp = Date()
+        await storage.saveAsync(autosens, as: Settings.autosense)
 
-            return autosens
-        } else {
-            return nil
-        }
+        return autosens
     }
 
     func createProfiles() async throws {
@@ -550,24 +558,24 @@ final class OpenAPS {
             let carbRatios = try JSONBridge.carbRatios(from: carbRatios)
             let tempTargets = try JSONBridge.tempTargets(from: tempTargets)
 
-            let pumpProfile = try OpenAPSSwift.makeProfile(
-                preferences: adjustedPreferences,
+            let pumpProfile = try ProfileGenerator.generate(
                 pumpSettings: pumpSettings,
                 bgTargets: bgTargets,
                 basalProfile: basalProfile,
-                insulinSensitivities: insulinSensitivities,
+                isf: insulinSensitivities,
+                preferences: adjustedPreferences,
                 carbRatios: carbRatios,
                 tempTargets: tempTargets,
                 model: model,
                 clock: clock
             )
 
-            let profile = try OpenAPSSwift.makeProfile(
-                preferences: adjustedPreferences,
+            let profile = try ProfileGenerator.generate(
                 pumpSettings: pumpSettings,
                 bgTargets: bgTargets,
                 basalProfile: basalProfile,
-                insulinSensitivities: insulinSensitivities,
+                isf: insulinSensitivities,
+                preferences: adjustedPreferences,
                 carbRatios: carbRatios,
                 tempTargets: tempTargets,
                 model: model,
@@ -588,88 +596,105 @@ final class OpenAPS {
 
     private func iob(
         pumphistory: [PumpHistoryEvent],
-        profile: JSON,
-        clock: JSON,
-        autosens: JSON
-    ) throws -> RawJSON {
+        profile: Profile,
+        clock: Date,
+        autosens: Autosens?
+    ) throws -> [IobResult] {
         // FIXME: For now we'll just remove duplicate suspends here (ISSUE-399)
         let pumphistory = pumphistory.removingDuplicateSuspendResumeEvents()
 
-        let swiftResult = OpenAPSSwift
-            .iob(pumphistory: pumphistory, profile: profile, clock: clock, autosens: autosens)
-        return try swiftResult.returnOrThrow()
+        return try IobGenerator.generate(
+            history: pumphistory,
+            profile: profile,
+            clock: clock,
+            autosens: autosens
+        )
     }
 
     private func meal(
         pumphistory: [PumpHistoryEvent],
-        profile: JSON,
-        basalProfile: JSON,
-        clock: JSON,
+        profile: Profile,
+        basalProfile: [BasalProfileEntry],
+        clock: Date,
         carbs: [CarbsEntry],
         glucose: [BloodGlucose]
-    ) throws -> RawJSON {
-        let swiftResult = OpenAPSSwift
-            .meal(
-                pumphistory: pumphistory,
-                profile: profile,
-                basalProfile: basalProfile,
-                clock: clock,
-                carbs: carbs,
-                glucose: glucose
-            )
-        return try swiftResult.returnOrThrow()
+    ) throws -> ComputedCarbs? {
+        try MealGenerator.generate(
+            pumpHistory: pumphistory,
+            profile: profile,
+            basalProfile: basalProfile,
+            clock: clock,
+            carbHistory: carbs,
+            glucoseHistory: glucose
+        )
     }
 
     private func autosense(
         glucose: [BloodGlucose],
         pumpHistory: [PumpHistoryEvent],
-        basalprofile: JSON,
-        profile: JSON,
+        basalProfile: [BasalProfileEntry],
+        profile: Profile,
         carbs: [CarbsEntry],
-        temptargets: JSON
-    ) throws -> RawJSON {
-        let swiftResult = OpenAPSSwift
-            .autosense(
-                glucose: glucose,
-                pumpHistory: pumpHistory,
-                basalProfile: basalprofile,
-                profile: profile,
-                carbs: carbs,
-                tempTargets: temptargets,
-                clock: Date()
-            )
-        return try swiftResult.returnOrThrow()
+        tempTargets: [TempTarget],
+        clock: Date
+    ) throws -> Autosens {
+        // this logic is from prepare/autosens.js
+        let ratio8h = try AutosensGenerator.generate(
+            glucose: glucose,
+            pumpHistory: pumpHistory,
+            basalProfile: basalProfile,
+            profile: profile,
+            carbs: carbs,
+            tempTargets: tempTargets,
+            maxDeviations: 96,
+            clock: clock
+        )
+
+        let ratio24h = try AutosensGenerator.generate(
+            glucose: glucose,
+            pumpHistory: pumpHistory,
+            basalProfile: basalProfile,
+            profile: profile,
+            carbs: carbs,
+            tempTargets: tempTargets,
+            maxDeviations: 288,
+            clock: clock
+        )
+
+        return ratio8h.ratio < ratio24h.ratio ? ratio8h : ratio24h
     }
 
     private func determineBasal(
         glucose: [BloodGlucose],
-        currentTemp: JSON,
-        iob: JSON,
-        profile: JSON,
-        autosens: JSON,
-        meal: JSON,
+        currentTemp: TempBasal,
+        iob: [IobResult],
+        profile: Profile,
+        autosens: Autosens?,
+        meal: ComputedCarbs?,
         microBolusAllowed: Bool,
-        reservoir: JSON,
-        preferences: JSON,
-        basalProfile: JSON,
-        trioCustomOrefVariables: JSON
-    ) throws -> RawJSON {
+        reservoir: Decimal,
+        preferences: Preferences,
+        trioCustomOrefVariables: TrioCustomOrefVariables
+    ) throws -> Determination? {
         let clock = Date()
-        let swiftResult = OpenAPSSwift.determineBasal(
-            glucose: glucose,
-            currentTemp: currentTemp,
-            iob: iob,
+
+        guard let meal = meal, let autosens = autosens else {
+            throw DeterminationError.missingInputs
+        }
+
+        return try DeterminationGenerator.generate(
             profile: profile,
-            autosens: autosens,
-            meal: meal,
-            microBolusAllowed: microBolusAllowed,
-            reservoir: reservoir,
             preferences: preferences,
-            basalProfile: basalProfile,
+            currentTemp: currentTemp,
+            iobData: iob,
+            mealData: meal,
+            autosensData: autosens,
+            reservoirData: reservoir,
+            glucose: glucose,
+            microBolusAllowed: microBolusAllowed,
             trioCustomOrefVariables: trioCustomOrefVariables,
-            clock: clock
+            currentTime: clock
         )
-        return try swiftResult.returnOrThrow()
     }
 
     private func loadJSON(name: String) -> String {

+ 0 - 35
Trio/Sources/APS/OpenAPSSwift/JSONBridge.swift

@@ -8,10 +8,6 @@ enum JSONError: Error {
 }
 
 enum JSONBridge {
-    static func preferences(from: JSON) throws -> Preferences {
-        try JSONBridge.from(string: from.rawJSON)
-    }
-
     static func pumpSettings(from: JSON) throws -> PumpSettings {
         try JSONBridge.from(string: from.rawJSON)
     }
@@ -40,49 +36,18 @@ enum JSONBridge {
         try JSONBridge.from(string: from.rawJSON)
     }
 
-    static func currentTemp(from: JSON) throws -> TempBasal {
-        try JSONBridge.from(string: from.rawJSON)
-    }
-
-    static func iobResult(from: JSON) throws -> [IobResult] {
-        try JSONBridge.from(string: from.rawJSON)
-    }
-
     static func profile(from: JSON) throws -> Profile {
         try JSONBridge.from(string: from.rawJSON)
     }
 
-    static func computedCarbs(from: JSON) throws -> ComputedCarbs? {
-        try JSONBridge.from(string: from.rawJSON)
-    }
-
     static func autosens(from: JSON) throws -> Autosens? {
         try JSONBridge.from(string: from.rawJSON)
     }
 
-    static func clock(from: JSON) throws -> Date {
-        let dateJson = from.rawJSON.replacingOccurrences(of: "\"", with: "").trimmingCharacters(in: .whitespacesAndNewlines)
-        if let date = Formatter.iso8601withFractionalSeconds.date(from: dateJson) ?? Formatter.iso8601
-            .date(from: dateJson)
-        {
-            return date
-        }
-
-        throw JSONError.invalidDate(from.rawJSON)
-    }
-
     static func from<T: Decodable>(string: String) throws -> T {
         guard let data = string.data(using: .utf8) else {
             throw JSONError.invalidString
         }
         return try JSONCoding.decoder.decode(T.self, from: data)
     }
-
-    static func to<T: Encodable>(_ value: T) throws -> String {
-        let data = try JSONCoding.encoder.encode(value)
-        guard let string = String(data: data, encoding: .utf8) else {
-            throw JSONError.encodingFailed
-        }
-        return string
-    }
 }

+ 1 - 1
Trio/Sources/APS/OpenAPSSwift/Models/IobResult.swift

@@ -1,6 +1,6 @@
 import Foundation
 
-struct IobResult: Codable {
+struct IobResult: JSON {
     static func from(iob: IobTotal, iobWithZeroTemp: IobTotal) -> IobResult {
         IobResult(
             iob: iob.iob,

+ 0 - 183
Trio/Sources/APS/OpenAPSSwift/OpenAPSSwift.swift

@@ -1,183 +0,0 @@
-import Foundation
-
-struct OpenAPSSwift {
-    static func makeProfile(
-        preferences: Preferences,
-        pumpSettings: PumpSettings,
-        bgTargets: BGTargets,
-        basalProfile: [BasalProfileEntry],
-        insulinSensitivities: InsulinSensitivities,
-        carbRatios: CarbRatios,
-        tempTargets: [TempTarget],
-        model: String,
-        clock: Date
-    ) throws -> Profile {
-        try ProfileGenerator.generate(
-            pumpSettings: pumpSettings,
-            bgTargets: bgTargets,
-            basalProfile: basalProfile,
-            isf: insulinSensitivities,
-            preferences: preferences,
-            carbRatios: carbRatios,
-            tempTargets: tempTargets,
-            model: model,
-            clock: clock
-        )
-    }
-
-    static func determineBasal(
-        glucose: [BloodGlucose],
-        currentTemp: JSON,
-        iob: JSON,
-        profile: JSON,
-        autosens: JSON,
-        meal: JSON,
-        microBolusAllowed: Bool,
-        reservoir: JSON,
-        preferences: JSON,
-        basalProfile: JSON,
-        trioCustomOrefVariables: JSON,
-        clock: Date
-    ) -> (OrefFunctionResult) {
-        do {
-            let currentTemp = try JSONBridge.currentTemp(from: currentTemp)
-            let iob = try JSONBridge.iobResult(from: iob)
-            let profile = try JSONBridge.profile(from: profile)
-            let autosens = try JSONBridge.autosens(from: autosens)
-            let meal = try JSONBridge.computedCarbs(from: meal)
-            let microBolusAllowed = microBolusAllowed
-            let reservoir = Decimal(string: reservoir.rawJSON)
-            let preferences = try JSONBridge.preferences(from: preferences)
-            let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
-            let trioCustomOrefVariables = try JSONBridge.trioCustomOrefVariables(from: trioCustomOrefVariables)
-
-            guard let mealData = meal, let autosensData = autosens else {
-                return .failure(DeterminationError.missingInputs)
-            }
-
-            let rawDetermination = try DeterminationGenerator.generate(
-                profile: profile,
-                preferences: preferences,
-                currentTemp: currentTemp,
-                iobData: iob,
-                mealData: mealData,
-                autosensData: autosensData,
-                reservoirData: reservoir ?? 100,
-                glucose: glucose,
-                microBolusAllowed: microBolusAllowed,
-                trioCustomOrefVariables: trioCustomOrefVariables,
-                currentTime: clock
-            )
-
-            return try .success(JSONBridge.to(rawDetermination))
-
-        } catch let determinationError as DeterminationError {
-            // if we get a determination error we want to return it as a JSON
-            // object that is { "error": "some error" }
-            do {
-                let response = try JSONBridge.to(DeterminationErrorResponse(error: determinationError.localizedDescription))
-                return .success(response)
-            } catch {
-                return .failure(determinationError)
-            }
-        } catch {
-            return .failure(error)
-        }
-    }
-
-    static func meal(
-        pumphistory: [PumpHistoryEvent],
-        profile: JSON,
-        basalProfile: JSON,
-        clock: JSON,
-        carbs: [CarbsEntry],
-        glucose: [BloodGlucose]
-    ) -> (OrefFunctionResult) {
-        do {
-            let profile = try JSONBridge.profile(from: profile)
-            let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
-            let clock = try JSONBridge.clock(from: clock)
-
-            let mealResult = try MealGenerator.generate(
-                pumpHistory: pumphistory,
-                profile: profile,
-                basalProfile: basalProfile,
-                clock: clock,
-                carbHistory: carbs,
-                glucoseHistory: glucose
-            )
-
-            return try .success(JSONBridge.to(mealResult))
-        } catch {
-            return .failure(error)
-        }
-    }
-
-    static func iob(pumphistory: [PumpHistoryEvent], profile: JSON, clock: JSON, autosens: JSON) -> (OrefFunctionResult) {
-        do {
-            let profile = try JSONBridge.profile(from: profile)
-            let clock = try JSONBridge.clock(from: clock)
-            let autosens = try JSONBridge.autosens(from: autosens)
-
-            let iobResult = try IobGenerator.generate(
-                history: pumphistory,
-                profile: profile,
-                clock: clock,
-                autosens: autosens
-            )
-
-            return try .success(JSONBridge.to(iobResult))
-        } catch {
-            return .failure(error)
-        }
-    }
-
-    static func autosense(
-        glucose: [BloodGlucose],
-        pumpHistory: [PumpHistoryEvent],
-        basalProfile: JSON,
-        profile: JSON,
-        carbs: [CarbsEntry],
-        tempTargets: JSON,
-        clock: JSON,
-        includeDeviationsForTesting: Bool = false
-    ) -> (OrefFunctionResult) {
-        do {
-            let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
-            let profile = try JSONBridge.profile(from: profile)
-            let tempTargets = try JSONBridge.tempTargets(from: tempTargets)
-            let clock = try JSONBridge.clock(from: clock)
-
-            // this logic is from prepare/autosens.js
-            let ratio8h = try AutosensGenerator.generate(
-                glucose: glucose,
-                pumpHistory: pumpHistory,
-                basalProfile: basalProfile,
-                profile: profile,
-                carbs: carbs,
-                tempTargets: tempTargets,
-                maxDeviations: 96,
-                clock: clock,
-                includeDeviationsForTesting: includeDeviationsForTesting
-            )
-
-            let ratio24h = try AutosensGenerator.generate(
-                glucose: glucose,
-                pumpHistory: pumpHistory,
-                basalProfile: basalProfile,
-                profile: profile,
-                carbs: carbs,
-                tempTargets: tempTargets,
-                maxDeviations: 288,
-                clock: clock,
-                includeDeviationsForTesting: includeDeviationsForTesting
-            )
-
-            let lowestRatio = ratio8h.ratio < ratio24h.ratio ? ratio8h : ratio24h
-
-            return try .success(JSONBridge.to(lowestRatio))
-        } catch {
-            return .failure(error)
-        }
-    }
-}

+ 0 - 13
Trio/Sources/APS/OpenAPSSwift/OrefFunctionResult.swift

@@ -1,13 +0,0 @@
-import Foundation
-
-enum OrefFunctionResult {
-    case success(RawJSON)
-    case failure(Error)
-
-    func returnOrThrow() throws -> RawJSON {
-        switch self {
-        case let .success(json): return json
-        case let .failure(error): throw error
-        }
-    }
-}

+ 7 - 0
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -121601,6 +121601,9 @@
         }
       }
     },
+    "End Snooze" : {
+
+    },
     "Endpoint" : {
       "localizations" : {
         "bg" : {
@@ -260220,6 +260223,9 @@
         }
       }
     },
+    "Swipe left to end snooze." : {
+
+    },
     "Swipe the chart to scroll through time." : {
       "localizations" : {
         "bg" : {
@@ -315137,6 +315143,7 @@
       }
     },
     "You can disable this feature anytime." : {
+      "extractionState" : "stale",
       "localizations" : {
         "bg" : {
           "stringUnit" : {

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

@@ -1,9 +1,5 @@
 import Foundation
 
-struct DeterminationErrorResponse: JSON, Equatable {
-    let error: String
-}
-
 struct Determination: JSON, Equatable {
     let id: UUID?
     var reason: String