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

replace glucose JSON in APSManager with CD entity parsed into JSON, thanks @dnzxy and @stkhlm

polscm32 пре 2 година
родитељ
комит
f35fc31de0

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -266,6 +266,7 @@
 		53F2382465BF74DB1A967C8B /* PumpConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8630D58BDAD6D9C650B9B39 /* PumpConfigProvider.swift */; };
 		581516A42BCED84A00BF67D7 /* DebuggingIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581516A32BCED84A00BF67D7 /* DebuggingIdentifiers.swift */; };
 		581516A92BCEEDF800BF67D7 /* NSPredicates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581516A82BCEEDF800BF67D7 /* NSPredicates.swift */; };
+		581AC4392BE22ED10038760C /* JSONConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581AC4382BE22ED10038760C /* JSONConverter.swift */; };
 		58237D9E2BCF0A6B00A47A79 /* PopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58237D9D2BCF0A6B00A47A79 /* PopupView.swift */; };
 		5825D1342BD4058F00F36E9B /* BGaverages+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5825D1062BD4058F00F36E9B /* BGaverages+CoreDataClass.swift */; };
 		5825D1352BD4058F00F36E9B /* BGaverages+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5825D1072BD4058F00F36E9B /* BGaverages+CoreDataProperties.swift */; };
@@ -886,6 +887,7 @@
 		505E09DC17A0C3D0AF4B66FE /* ISFEditorStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ISFEditorStateModel.swift; sourceTree = "<group>"; };
 		581516A32BCED84A00BF67D7 /* DebuggingIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggingIdentifiers.swift; sourceTree = "<group>"; };
 		581516A82BCEEDF800BF67D7 /* NSPredicates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicates.swift; sourceTree = "<group>"; };
+		581AC4382BE22ED10038760C /* JSONConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONConverter.swift; sourceTree = "<group>"; };
 		58237D9D2BCF0A6B00A47A79 /* PopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupView.swift; sourceTree = "<group>"; };
 		5825D1062BD4058F00F36E9B /* BGaverages+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BGaverages+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
 		5825D1072BD4058F00F36E9B /* BGaverages+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BGaverages+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
@@ -2215,6 +2217,7 @@
 				5837A5312BD2E81100A5DC04 /* InsulinStored+helper.swift */,
 				CC76E9502BD4812E008BEB61 /* Forecast+helper.swift */,
 				5887527B2BD986E1008B081D /* OpenAPSBattery.swift */,
+				581AC4382BE22ED10038760C /* JSONConverter.swift */,
 			);
 			path = Helper;
 			sourceTree = "<group>";
@@ -3104,6 +3107,7 @@
 				5D16287A969E64D18CE40E44 /* PumpConfigStateModel.swift in Sources */,
 				19D466AA29AA3099004D5F33 /* FPUConfigRootView.swift in Sources */,
 				E974172296125A5AE99E634C /* PumpConfigRootView.swift in Sources */,
+				581AC4392BE22ED10038760C /* JSONConverter.swift in Sources */,
 				CE7CA3522A064973004BE681 /* ListTempPresetsIntent.swift in Sources */,
 				448B6FCB252BD4796E2960C0 /* PumpSettingsEditorDataFlow.swift in Sources */,
 				38E44536274E411700EC9A94 /* Disk.swift in Sources */,

+ 97 - 163
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -11,6 +11,8 @@ final class OpenAPS {
 
     let context = CoreDataStack.shared.backgroundContext
 
+    let jsonConverter = JSONConverter()
+
     init(storage: FileStorage) {
         self.storage = storage
     }
@@ -93,54 +95,15 @@ final class OpenAPS {
     }
 
     // fetch glucose to pass it to the meal function and to determine basal
-
     private func fetchGlucose() -> [GlucoseStored]? {
         do {
-            return try context.fetch(GlucoseStored.fetch(ascending: false, fetchLimit: 5))
+            return try context.fetch(GlucoseStored.fetch(ascending: false, fetchLimit: 3))
         } catch {
             print("failed")
             return []
         }
     }
 
-//    private func fetchGlucose() -> GlucoseStored? {
-//        do {
-//            return try context.fetch(GlucoseStored.fetch(ascending: false, fetchLimit: 1)).first
-//        } catch {
-//            print("failed")
-//            return nil
-//        }
-//    }
-
-//    private func fetchGlucose() -> GlucoseStored? {
-//        do {
-//            debugPrint("OpenAPS: \(#function) \(DebuggingIdentifiers.succeeded) fetched glucose")
-//
-    ////            let fr = NSFetchRequest<GlucoseStored>(entityName: "GlucoseStored")
-//            let fr = GlucoseStored.fetchRequest()
-//            fr.resultType = .dictionaryResultType
-//            fr.fetchLimit = 1
-//            fr.predicate = NSPredicate.predicateFor30MinAgo
-//            fr.sortDescriptors = [NSSortDescriptor(keyPath: \GlucoseStored.date, ascending: false)]
-//            let last = try context.fetch(fr)
-//
-//            return last.first
-//        } catch {
-//            debugPrint("OpenAPS: \(#function) \(DebuggingIdentifiers.failed) failed to fetch glucose with error: \(error)")
-//            return nil
-//        }
-//    }
-
-    func convertDataToJSON(data: Data) -> Any? {
-        do {
-            let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
-            return jsonObject
-        } catch {
-            print("ich bin ein hurensohn")
-            return nil
-        }
-    }
-
     func determineBasal(currentTemp: TempBasal, clock: Date = Date()) -> Future<Determination?, Never> {
         Future { promise in
             self.processQueue.async {
@@ -155,129 +118,92 @@ final class OpenAPS {
                 // meal
                 let pumpHistory = self.loadFileFromStorage(name: OpenAPS.Monitor.pumpHistory)
                 let carbs = self.loadFileFromStorage(name: Monitor.carbHistory)
-//                let glucose = self.loadFileFromStorage(name: Monitor.glucose)
-
-                /// get glucose from CD
-                do {
-                    let glucose = self.fetchGlucose()
-                    let encoder = JSONEncoder()
-                    encoder.keyEncodingStrategy = .useDefaultKeys
-                    let glucoseJSON = try encoder.encode(glucose) /// returns data
-                    ///
-
-//                    let json = try JSONSerialization.jsonObject(with: glucoseJSON, options: [])
-                    let string = String(data: glucoseJSON, encoding: .utf8)
-                    print("**************\(string)")
-//                    let glucoseJSON = try glucose.map { try JSONSerialization.data(withJSONObject: $0) }
-//                    let test = String(data: glucoseJSON!, encoding: .utf8)
-
-//                    let glucoseArray = glucose?.compactMap { try $0.encodeToJson() }
-
-//                    if let jsonObject = convertDataToJSON(data: glucoseArray) as? [String: Any] {}
-
-//                    let jsonData = try GlucoseStored.encodeToJson(glucose ?? GlucoseStored())
-//                    let jsonData = try glucose?.encodeToJson()
-
-//                    if let json = convertDataToJSON(data: jsonData) as? [String: Any] {
-//                        print
-//                    }
-//                    let jsonString = String(data: jsonData!, encoding: .utf8)
-//                    print(jsonString ?? "Invalid JSON")
-
-                    let profile = self.loadFileFromStorage(name: Settings.profile)
-                    let basalProfile = self.loadFileFromStorage(name: Settings.basalProfile)
-
-                    let meal = self.meal(
-                        pumphistory: pumpHistory,
-                        profile: profile,
-                        basalProfile: basalProfile,
-                        clock: clock,
-                        carbs: carbs,
-                        glucose: string ?? ""
-                    )
-
-                    self.storage.save(meal, as: Monitor.meal)
-
-                    // iob
-                    let autosens = self.loadFileFromStorage(name: Settings.autosense)
-                    let iob = self.iob(
-                        pumphistory: pumpHistory,
-                        profile: profile,
-                        clock: clock,
-                        autosens: autosens.isEmpty ? .null : autosens
-                    )
-
-                    self.storage.save(iob, as: Monitor.iob)
-
-                    // determine-basal
-                    let reservoir = self.loadFileFromStorage(name: Monitor.reservoir)
-
-                    let preferences = self.loadFileFromStorage(name: Settings.preferences)
-
-                    // oref2
-                    let oref2_variables = self.oref2()
-
-                    let orefDetermination = self.determineBasal(
-                        glucose: string ?? "",
-                        currentTemp: tempBasal,
-                        iob: iob,
-                        profile: profile,
-                        autosens: autosens.isEmpty ? .null : autosens,
-                        meal: meal,
-                        microBolusAllowed: true,
-                        reservoir: reservoir,
-                        pumpHistory: pumpHistory,
-                        preferences: preferences,
-                        basalProfile: basalProfile,
-                        oref2_variables: oref2_variables
-                    )
-                    debug(.openAPS, "Determinated: \(orefDetermination)")
-
-                    if var determination = Determination(from: orefDetermination) {
-                        determination.timestamp = determination.deliverAt ?? clock
-                        self.storage.save(determination, as: Enact.suggested)
-
-                        // save to core data asynchronously
-                        self.processDetermination(determination)
-
-                        if determination.tdd ?? 0 > 0 {
-                            self.context.perform {
-                                let saveToTDD = TDD(context: self.context)
-
-                                saveToTDD.timestamp = determination.timestamp ?? Date()
-                                saveToTDD.tdd = (determination.tdd ?? 0) as NSDecimalNumber?
-                                if self.context.hasChanges {
-                                    try? self.context.save()
-                                }
-
-                                let saveTarget = Target(context: self.context)
-                                saveTarget.current = (determination.current_target ?? 100) as NSDecimalNumber?
-                                if self.context.hasChanges {
-                                    try? self.context.save()
-                                }
-                            }
-                        }
 
-                        promise(.success(determination))
-                    } else {
-                        promise(.success(nil))
-                    }
-                } catch {
-                    print("Encoding failed with error: \(error)")
-                }
+                /// glucose
+                let glucose = self.fetchGlucose()
+//                    let glucoseString = self.convertToJSON(glucose)
+                let glucoseString = self.jsonConverter.convertToJSON(glucose)
+
+                /// profile
+                let profile = self.loadFileFromStorage(name: Settings.profile)
+                let basalProfile = self.loadFileFromStorage(name: Settings.basalProfile)
+
+                /// meal
+                let meal = self.meal(
+                    pumphistory: pumpHistory,
+                    profile: profile,
+                    basalProfile: basalProfile,
+                    clock: clock,
+                    carbs: carbs,
+                    glucose: glucoseString
+                )
+
+                self.storage.save(meal, as: Monitor.meal)
+
+                // iob
+                let autosens = self.loadFileFromStorage(name: Settings.autosense)
+                let iob = self.iob(
+                    pumphistory: pumpHistory,
+                    profile: profile,
+                    clock: clock,
+                    autosens: autosens.isEmpty ? .null : autosens
+                )
+
+                self.storage.save(iob, as: Monitor.iob)
 
-                /// convert glucoseStored to JSON
+                // determine-basal
+                let reservoir = self.loadFileFromStorage(name: Monitor.reservoir)
 
-//                    let glucoseValue: Decimal? = Decimal(glucoseRecord.glucose)
+                let preferences = self.loadFileFromStorage(name: Settings.preferences)
 
-//                    let glucoseStoredJSON = BloodGlucose(
-//                        date: Decimal(Int((glucoseStored.first?.date?.timeIntervalSince1970 ?? 0) * 1000)),
-//                        dateString: glucoseRecord.date ?? Date(),
-//                        unfiltered: glucoseValue,
-//                        filtered: glucoseValue,
-//                        noise: nil,
-//                        type: ""
-//                    )
+                // oref2
+                let oref2_variables = self.oref2()
+
+                let orefDetermination = self.determineBasal(
+                    glucose: glucoseString,
+                    currentTemp: tempBasal,
+                    iob: iob,
+                    profile: profile,
+                    autosens: autosens.isEmpty ? .null : autosens,
+                    meal: meal,
+                    microBolusAllowed: true,
+                    reservoir: reservoir,
+                    pumpHistory: pumpHistory,
+                    preferences: preferences,
+                    basalProfile: basalProfile,
+                    oref2_variables: oref2_variables
+                )
+                debug(.openAPS, "Determinated: \(orefDetermination)")
+
+                if var determination = Determination(from: orefDetermination) {
+                    determination.timestamp = determination.deliverAt ?? clock
+                    self.storage.save(determination, as: Enact.suggested)
+
+                    // save to core data asynchronously
+                    self.processDetermination(determination)
+
+                    if determination.tdd ?? 0 > 0 {
+                        self.context.perform {
+                            let saveToTDD = TDD(context: self.context)
+
+                            saveToTDD.timestamp = determination.timestamp ?? Date()
+                            saveToTDD.tdd = (determination.tdd ?? 0) as NSDecimalNumber?
+                            if self.context.hasChanges {
+                                try? self.context.save()
+                            }
+
+                            let saveTarget = Target(context: self.context)
+                            saveTarget.current = (determination.current_target ?? 100) as NSDecimalNumber?
+                            if self.context.hasChanges {
+                                try? self.context.save()
+                            }
+                        }
+                    }
+
+                    promise(.success(determination))
+                } else {
+                    promise(.success(nil))
+                }
             }
         }
     }
@@ -471,12 +397,16 @@ final class OpenAPS {
                 debug(.openAPS, "Start autosens")
                 let pumpHistory = self.loadFileFromStorage(name: OpenAPS.Monitor.pumpHistory)
                 let carbs = self.loadFileFromStorage(name: Monitor.carbHistory)
-                let glucose = self.loadFileFromStorage(name: Monitor.glucose)
+
+                /// glucose
+                let glucose = self.fetchGlucose()
+                let glucoseString = self.jsonConverter.convertToJSON(glucose)
+
                 let profile = self.loadFileFromStorage(name: Settings.profile)
                 let basalProfile = self.loadFileFromStorage(name: Settings.basalProfile)
                 let tempTargets = self.loadFileFromStorage(name: Settings.tempTargets)
                 let autosensResult = self.autosense(
-                    glucose: glucose,
+                    glucose: glucoseString,
                     pumpHistory: pumpHistory,
                     basalprofile: basalProfile,
                     profile: profile,
@@ -501,7 +431,11 @@ final class OpenAPS {
             self.processQueue.async {
                 debug(.openAPS, "Start autotune")
                 let pumpHistory = self.loadFileFromStorage(name: OpenAPS.Monitor.pumpHistory)
-                let glucose = self.loadFileFromStorage(name: Monitor.glucose)
+
+                /// glucose
+                let glucose = self.fetchGlucose()
+                let glucoseString = self.jsonConverter.convertToJSON(glucose)
+
                 let profile = self.loadFileFromStorage(name: Settings.profile)
                 let pumpProfile = self.loadFileFromStorage(name: Settings.pumpProfile)
                 let carbs = self.loadFileFromStorage(name: Monitor.carbHistory)
@@ -509,7 +443,7 @@ final class OpenAPS {
                 let autotunePreppedGlucose = self.autotunePrepare(
                     pumphistory: pumpHistory,
                     profile: profile,
-                    glucose: glucose,
+                    glucose: glucoseString,
                     pumpprofile: pumpProfile,
                     carbs: carbs,
                     categorizeUamAsBasal: categorizeUamAsBasal,

+ 0 - 2
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -140,8 +140,6 @@ extension Settings {
                                 .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcementsEnacted), from: self)
                             Text("Autotune")
                                 .navigationLink(to: .configEditor(file: OpenAPS.Settings.autotune), from: self)
-                            Text("Glucose")
-                                .navigationLink(to: .configEditor(file: OpenAPS.Monitor.glucose), from: self)
                         }
 
                         Group {

+ 0 - 15
Model/Helper/GlucoseStored+helper.swift

@@ -20,19 +20,6 @@ extension GlucoseStored {
 
         return lastThreeValues.allSatisfy { $0.glucose == firstValue }
     }
-
-//    static func asyncFetch(_ predicate: NSPredicate = NSPredicate(value: true), completion: @escaping (NSAsynchronousFetchResult<GlucoseStored>)->Void) -> NSAsynchronousFetchRequest<GlucoseStored> {
-//           let request: NSFetchRequest<GlucoseStored> = GlucoseStored.fetchRequest()
-//           request.sortDescriptors = [NSSortDescriptor(keyPath: \GlucoseStored.date, ascending: true)]
-//           request.predicate = predicate
-//
-//           // Erstelle einen NSAsynchronousFetchRequest mit einem Completion Handler
-//           let asyncFetchRequest = NSAsynchronousFetchRequest<GlucoseStored>(fetchRequest: request) { result in
-//               completion(result)
-//           }
-//
-//           return asyncFetchRequest
-//       }
 }
 
 extension NSPredicate {
@@ -63,8 +50,6 @@ extension GlucoseStored: Encodable {
     public func encode(to encoder: Encoder) throws {
         var container = encoder.container(keyedBy: CodingKeys.self)
 
-//        let dateFormatter = ISO8601DateFormatter()
-//        let dateString = dateFormatter.string(from: date ?? Date())
         let dateString = String(format: "%.0f", (date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000)
         try container.encode(dateString, forKey: .date)
         try container.encode(direction, forKey: .direction)

+ 21 - 0
Model/Helper/JSONConverter.swift

@@ -0,0 +1,21 @@
+import Foundation
+
+class JSONConverter {
+    /// this is temporarily used to parse the fetched Core Data objects to JSON in order to pass it to DetermineBasal()
+    func convertToJSON<T: Encodable>(_ value: T?) -> String {
+        guard let value = value else { return "" }
+
+        let encoder = JSONEncoder()
+        encoder.keyEncodingStrategy = .useDefaultKeys
+        do {
+            let jsonData = try encoder.encode(value)
+            if let jsonString = String(data: jsonData, encoding: .utf8) {
+                return jsonString
+            }
+        } catch {
+            debugPrint("\(DebuggingIdentifiers.failed) could not convert object to JSON: \(error)")
+        }
+
+        return "could not convert object to JSON"
+    }
+}