ソースを参照

More CoreData and stat related bugs

Jon Mårtensson 3 年 前
コミット
d10c45e3e0

+ 4 - 0
BGaverages+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(BGaverages) public class BGaverages: NSManagedObject {}

+ 15 - 0
BGaverages+CoreDataProperties.swift

@@ -0,0 +1,15 @@
+import CoreData
+import Foundation
+
+public extension BGaverages {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<BGaverages> {
+        NSFetchRequest<BGaverages>(entityName: "BGaverages")
+    }
+
+    @NSManaged var date: Date?
+    @NSManaged var average: NSDecimalNumber?
+    @NSManaged var average_1: NSDecimalNumber?
+    @NSManaged var average_7: NSDecimalNumber?
+    @NSManaged var average_30: NSDecimalNumber?
+    @NSManaged var average_90: NSDecimalNumber?
+}

+ 4 - 0
BGmedian+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(BGmedian) public class BGmedian: NSManagedObject {}

+ 15 - 0
BGmedian+CoreDataProperties.swift

@@ -0,0 +1,15 @@
+import CoreData
+import Foundation
+
+public extension BGmedian {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<BGmedian> {
+        NSFetchRequest<BGmedian>(entityName: "BGmedian")
+    }
+
+    @NSManaged var date: Date?
+    @NSManaged var median: NSDecimalNumber?
+    @NSManaged var median_1: NSDecimalNumber?
+    @NSManaged var median_30: NSDecimalNumber?
+    @NSManaged var median_90: NSDecimalNumber?
+    @NSManaged var median_7: NSDecimalNumber?
+}

+ 36 - 0
Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents

@@ -1,16 +1,51 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22C65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
+    <entity name="BGaverages" representedClassName="BGaverages" syncable="YES" codeGenerationType="class">
+        <attribute name="average" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="average_1" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="average_7" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="average_30" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="average_90" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+    </entity>
+    <entity name="BGmedian" representedClassName="BGmedian" syncable="YES" codeGenerationType="class">
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="median" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="median_1" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="median_7" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="median_30" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="median_90" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+    </entity>
     <entity name="Carbohydrates" representedClassName="Carbohydrates" syncable="YES" codeGenerationType="class">
         <attribute name="carbs" optional="YES" attributeType="Decimal" defaultValueString="0"/>
         <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <attribute name="enteredBy" optional="YES" attributeType="String"/>
     </entity>
+    <entity name="HbA1c" representedClassName="HbA1c" syncable="YES" codeGenerationType="class">
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="hba1c" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="hba1c_1" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="hba1c_7" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="hba1c_30" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="hba1c_90" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+    </entity>
+    <entity name="InsulinDistribution" representedClassName="InsulinDistribution" syncable="YES" codeGenerationType="class">
+        <attribute name="bolus" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="scheduledBasal" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="tempBasal" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <relationship name="insulin" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Oref0Suggestion" inverseName="computedInsulinDistribution" inverseEntity="Oref0Suggestion"/>
+    </entity>
     <entity name="LoopStatRecord" representedClassName="LoopStatRecord" syncable="YES" codeGenerationType="class">
         <attribute name="duration" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
         <attribute name="end" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <attribute name="loopStatus" optional="YES" attributeType="String"/>
         <attribute name="start" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
     </entity>
+    <entity name="Oref0Suggestion" representedClassName="Oref0Suggestion" syncable="YES" codeGenerationType="class">
+        <relationship name="computedInsulinDistribution" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="InsulinDistribution" inverseName="insulin" inverseEntity="InsulinDistribution"/>
+        <relationship name="computedTDD" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TDD" inverseName="computed" inverseEntity="TDD"/>
+    </entity>
     <entity name="Readings" representedClassName="Readings" syncable="YES" codeGenerationType="class">
         <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <attribute name="glucose" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
@@ -18,5 +53,6 @@
     <entity name="TDD" representedClassName="TDD" syncable="YES" codeGenerationType="class">
         <attribute name="tdd" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <relationship name="computed" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Oref0Suggestion" inverseName="computedTDD" inverseEntity="Oref0Suggestion"/>
     </entity>
 </model>

+ 30 - 0
FreeAPS.xcworkspace/contents.xcworkspacedata

@@ -5,6 +5,36 @@
       location = "container:"
       name = "CoreDataClassesAndProperties">
       <FileRef
+         location = "group:InsulinDistribution+CoreDataClass.swift">
+      </FileRef>
+      <FileRef
+         location = "group:InsulinDistribution+CoreDataProperties.swift">
+      </FileRef>
+      <FileRef
+         location = "group:Oref0Suggestion+CoreDataClass.swift">
+      </FileRef>
+      <FileRef
+         location = "group:Oref0Suggestion+CoreDataProperties.swift">
+      </FileRef>
+      <FileRef
+         location = "group:HbA1c+CoreDataClass.swift">
+      </FileRef>
+      <FileRef
+         location = "group:HbA1c+CoreDataProperties.swift">
+      </FileRef>
+      <FileRef
+         location = "group:BGmedian+CoreDataClass.swift">
+      </FileRef>
+      <FileRef
+         location = "group:BGmedian+CoreDataProperties.swift">
+      </FileRef>
+      <FileRef
+         location = "group:BGaverages+CoreDataClass.swift">
+      </FileRef>
+      <FileRef
+         location = "group:BGaverages+CoreDataProperties.swift">
+      </FileRef>
+      <FileRef
          location = "group:Carbohydrates+CoreDataClass.swift">
       </FileRef>
       <FileRef

+ 62 - 49
FreeAPS/Sources/APS/APSManager.swift

@@ -682,21 +682,15 @@ final class BaseAPSManager: APSManager, Injectable {
         let preferences = settingsManager.preferences
         let currentTDD = enacted_.tdd ?? 0
 
-        // MARK: Add new data to Core Data:TDD Entity. TEST:
+        // MARK: Fetch data from Core Data: TDD Entity. TEST:
 
         if currentTDD > 0 {
-            debug(.apsManager, "Writing TDD to CoreData")
-            let nTDD = TDD(context: coredataContext)
-            nTDD.timestamp = Date()
-            nTDD.tdd = currentTDD as NSDecimalNumber
-            try? coredataContext.save()
-
-            let twoWeeksAgo = Date().addingTimeInterval(-10.days.timeInterval)
+            let tenDaysAgo = Date().addingTimeInterval(-10.days.timeInterval)
             let twoHoursAgo = Date().addingTimeInterval(-2.hours.timeInterval)
 
             var requestTDD = TDD.fetchRequest() as NSFetchRequest<TDD>
-            requestTDD.predicate = NSPredicate(format: "timestamp > %@ AND tdd > 0", twoWeeksAgo as NSDate)
-            let sortTDD = NSSortDescriptor(key: "timestamp", ascending: false)
+            requestTDD.predicate = NSPredicate(format: "timestamp > %@ AND tdd > 0", tenDaysAgo as NSDate)
+            let sortTDD = NSSortDescriptor(key: "timestamp", ascending: true)
             requestTDD.sortDescriptors = [sortTDD]
             var uniqEvents = [TDD]()
 
@@ -705,13 +699,12 @@ final class BaseAPSManager: APSManager, Injectable {
             var total: Decimal = 0
             var indeces: Decimal = 0
             for uniqEvent in uniqEvents {
-                debug(.apsManager, "Read TDD from CoreData: \(uniqEvent.tdd?.decimalValue ?? 0)")
                 total += uniqEvent.tdd?.decimalValue ?? 0
                 indeces += 1
             }
 
             requestTDD.predicate = NSPredicate(format: "timestamp > %@", twoHoursAgo as NSDate)
-            let sortTDDs = NSSortDescriptor(key: "timestamp", ascending: false)
+            let sortTDDs = NSSortDescriptor(key: "timestamp", ascending: true)
             requestTDD.sortDescriptors = [sortTDDs]
             var entriesPast2hours = [TDD]()
 
@@ -856,12 +849,12 @@ final class BaseAPSManager: APSManager, Injectable {
         requestLSR.predicate = NSPredicate(format: "start > %@", Date().addingTimeInterval(-24.hours.timeInterval) as NSDate)
         let sortLSR = NSSortDescriptor(key: "start", ascending: false)
         requestLSR.sortDescriptors = [sortLSR]
-        var lsr: [LoopStatRecord] = []
+        var lsr = [LoopStatRecord]()
         try? lsr = coredataContext.fetch(requestLSR)
 
         var successRate: Double?
-        var successNR = 0.0
-        var errorNR = 0.0
+        var successNR = 0
+        var errorNR = 0
         var minimumInt = 999.0
         var maximumInt = 0.0
         var minimumLoopTime = 9999.0
@@ -885,11 +878,12 @@ final class BaseAPSManager: APSManager, Injectable {
                 if let loopEnd = each.end {
                     let loopDuration = each.duration
 
-                    if (each.loopStatus?.contains("Success")) != nil {
+                    if each.loopStatus!.contains("Success") {
                         successNR += 1
                     } else {
                         errorNR += 1
                     }
+
                     i += 1
                     timeIntervalLoops = (previousTimeLoop - (each.start ?? previousTimeLoop)).timeInterval / 60
 
@@ -904,8 +898,7 @@ final class BaseAPSManager: APSManager, Injectable {
                     }
                     timeForOneLoop = loopDuration
                     timeForOneLoopArray.append(timeForOneLoop)
-                    averageLoopTime += timeForOneLoop
-
+                   
                     if timeForOneLoop >= maximumLoopTime, timeForOneLoop != 0.0 {
                         maximumLoopTime = timeForOneLoop
                     }
@@ -915,8 +908,14 @@ final class BaseAPSManager: APSManager, Injectable {
                     previousTimeLoop = loopEnd
                 }
             }
-            successRate = (successNR / Double(i)) * 100
-            averageLoopTime /= Double(i)
+            successRate = (Double(successNR) / Double(i)) * 100
+
+            // Average Loop Interval in minutes
+            let timeOfFirstIndex = lsr[0].start ?? Date()
+            let lastIndexWithTimestamp = lsr.count - 1
+            let timeOfLastIndex = lsr[lastIndexWithTimestamp].end ?? Date()
+            averageLoopTime = (timeOfFirstIndex - timeOfLastIndex).timeInterval / 60 / Double(errorNR + successNR)
+
             // Median values
             medianLoopTime = medianCalculation(array: timeForOneLoopArray)
             medianInterval = medianCalculation(array: timeIntervalLoopArray)
@@ -931,7 +930,7 @@ final class BaseAPSManager: APSManager, Injectable {
         }
 
         let requestGFS = Readings.fetchRequest() as NSFetchRequest<Readings>
-        let sortGlucose = NSSortDescriptor(key: "date", ascending: true)
+        let sortGlucose = NSSortDescriptor(key: "date", ascending: false)
         requestGFS.sortDescriptors = [sortGlucose]
 
         var glucose: [Readings] = []
@@ -939,7 +938,8 @@ final class BaseAPSManager: APSManager, Injectable {
 
         let firstElementTime = glucose.first?.date ?? Date()
         let lastElementTime = glucose.last?.date ?? Date()
-        let numberOfDays = (lastElementTime - firstElementTime).timeInterval / 8.64E4
+        var currentIndexTime = firstElementTime
+        let numberOfDays = (firstElementTime - lastElementTime).timeInterval / 8.64E4
 
         // Time In Range (%) and Average Glucose (24 hours). This will be refactored later after some testing.
         let length_ = glucose.count
@@ -970,30 +970,31 @@ final class BaseAPSManager: APSManager, Injectable {
 
         // Make arrays for median calculations and calculate averages
         if endIndex >= 0 {
-            for entry in glucose {
+            repeat {
                 j += 1
-                if entry.glucose > 0 {
-                    bg += Decimal(entry.glucose) * conversionFactor
-                    bgArray.append(Double(entry.glucose) * Double(conversionFactor))
-                    bgArrayForTIR.append((Double(entry.glucose), entry.date!))
+                if glucose[j].glucose > 0 {
+                    currentIndexTime = glucose[j].date ?? firstElementTime
+                    bg += Decimal(glucose[j].glucose) * conversionFactor
+                    bgArray.append(Double(glucose[j].glucose) * Double(conversionFactor))
+                    bgArrayForTIR.append((Double(glucose[j].glucose), glucose[j].date!))
                     nr_bgs += 1
-                    if (firstElementTime - (entry.date ?? Date())).timeInterval / 60 <= 8.64E4 { // 1 day
+                    if (firstElementTime - currentIndexTime).timeInterval / 60 <= 8.64E4 { // 1 day
                         bg_1 = bg / nr_bgs
                         bgArray_1 = bgArrayForTIR
                         bgArray_1_ = bgArray
                     }
-                    if (firstElementTime - (entry.date ?? Date())).timeInterval / 60 <= 6.048E5 { // 7 days
+                    if (firstElementTime - currentIndexTime).timeInterval / 60 <= 6.048E5 { // 7 days
                         bg_7 = bg / nr_bgs
                         bgArray_7 = bgArrayForTIR
                         bgArray_7_ = bgArray
                     }
-                    if (firstElementTime - (entry.date ?? Date())).timeInterval / 60 <= 2.592E6 { // 30 days
+                    if (firstElementTime - currentIndexTime).timeInterval / 60 <= 2.592E6 { // 30 days
                         bg_30 = bg / nr_bgs
                         bgArray_30 = bgArrayForTIR
                         bgArray_30_ = bgArray
                     }
                 }
-            }
+            } while j != glucose.count - 1
         }
 
         if nr_bgs > 0 {
@@ -1118,8 +1119,8 @@ final class BaseAPSManager: APSManager, Injectable {
         let nrOfCGMReadings = glucose24Hours?.count ?? 0
 
         let loopstat = LoopCycles(
-            loops: Int(successNR + errorNR),
-            errors: Int(errorNR),
+            loops: successNR + errorNR,
+            errors: errorNR,
             readings: nrOfCGMReadings,
             success_rate: Decimal(round(successRate ?? 0)),
             avg_interval: roundDecimal(Decimal(averageIntervalLoops), 1),
@@ -1178,35 +1179,47 @@ final class BaseAPSManager: APSManager, Injectable {
 
         let avg = Averages(Average: avgs, Median: median)
 
-        let suggestion = storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
+        // MARK: Fetch InsulinDuration from CoreData
+
+        // let suggestion = storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
+
+        let requestInsulinDistribution = InsulinDistribution.fetchRequest() as NSFetchRequest<InsulinDistribution>
+        let hoursAgo_ = Date().addingTimeInterval(-1.hours.timeInterval)
+        requestInsulinDistribution.predicate = NSPredicate(format: "date > %@", hoursAgo_ as NSDate)
+        let sortInsulin = NSSortDescriptor(key: "date", ascending: true)
+        requestInsulinDistribution.sortDescriptors = [sortInsulin]
+        requestInsulinDistribution.fetchLimit = 1
+
+        var insulinDistribution = [InsulinDistribution]()
+        try? insulinDistribution = coredataContext.fetch(requestInsulinDistribution)
 
         let insulin = Ins(
             TDD: roundDecimal(currentTDD, 2),
-            bolus: suggestion?.insulin?.bolus ?? 0,
-            temp_basal: suggestion?.insulin?.temp_basal ?? 0,
-            scheduled_basal: suggestion?.insulin?.scheduled_basal ?? 0
+            bolus: (insulinDistribution[0].bolus ?? 0) as Decimal,
+            temp_basal: (insulinDistribution[0].tempBasal ?? 0) as Decimal,
+            scheduled_basal: (insulinDistribution[0].scheduledBasal ?? 0) as Decimal
         )
 
-        var sumOfSquares: Decimal = 0
-        var sumOfSquares_1: Decimal = 0
-        var sumOfSquares_7: Decimal = 0
-        var sumOfSquares_30: Decimal = 0
+        var sumOfSquares = 0.0
+        var sumOfSquares_1 = 0.0
+        var sumOfSquares_7 = 0.0
+        var sumOfSquares_30 = 0.0
 
         // Total
         for array in bgArray {
-            sumOfSquares += pow(Decimal(array) - bg_total, 2)
+            sumOfSquares += pow(array - Double(bg_total), 2)
         }
         // One day
         for array_1 in bgArray_1_ {
-            sumOfSquares_1 += pow(Decimal(array_1) - bg_1, 2)
+            sumOfSquares_1 += pow(array_1 - Double(bg_1), 2)
         }
         // week
         for array_7 in bgArray_7_ {
-            sumOfSquares_7 += pow(Decimal(array_7) - bg_7, 2)
+            sumOfSquares_7 += pow(array_7 - Double(bg_7), 2)
         }
         // month
         for array_30 in bgArray_30_ {
-            sumOfSquares_30 += pow(Decimal(array_30) - bg_30, 2)
+            sumOfSquares_30 += pow(array_30 - Double(bg_30), 2)
         }
 
         // Standard deviation and Coefficient of variation
@@ -1221,19 +1234,19 @@ final class BaseAPSManager: APSManager, Injectable {
 
         // Avoid division by zero
         if bg_total > 0 {
-            sd_total = sqrt(Double(sumOfSquares / nr_bgs))
+            sd_total = sqrt(sumOfSquares / Double(nr_bgs))
             cv_total = sd_total / Double(bg_total) * 100
         }
         if bg_1 > 0 {
-            sd_1 = sqrt(Double(sumOfSquares_1) / Double(bgArray_1_.count))
+            sd_1 = sqrt(sumOfSquares_1 / Double(bgArray_1_.count))
             cv_1 = sd_1 / Double(bg_1) * 100
         }
         if bg_7 > 0 {
-            sd_7 = sqrt(Double(sumOfSquares_7) / Double(bgArray_7_.count))
+            sd_7 = sqrt(sumOfSquares_7 / Double(bgArray_7_.count))
             cv_7 = sd_7 / Double(bg_7) * 100
         }
         if bg_30 > 0 {
-            sd_30 = sqrt(Double(sumOfSquares_30) / Double(bgArray_30_.count))
+            sd_30 = sqrt(sumOfSquares_30 / Double(bgArray_30_.count))
             cv_30 = sd_30 / Double(bg_30) * 100
         }
 

+ 19 - 0
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -1,4 +1,5 @@
 import Combine
+import CoreData
 import Foundation
 import JavaScriptCore
 
@@ -8,6 +9,8 @@ final class OpenAPS {
 
     private let storage: FileStorage
 
+    let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
+
     init(storage: FileStorage) {
         self.storage = storage
     }
@@ -79,6 +82,22 @@ final class OpenAPS {
                     suggestion.timestamp = suggestion.deliverAt ?? clock
                     self.storage.save(suggestion, as: Enact.suggested)
 
+                    // MARK: Save to CoreData also. To do: Remove JSON saving
+
+                    if suggestion.tdd ?? 0 > 0 {
+                        let saveToTDD = TDD(context: self.coredataContext)
+                        saveToTDD.timestamp = suggestion.timestamp ?? Date()
+                        saveToTDD.tdd = (suggestion.tdd ?? 0) as NSDecimalNumber?
+                        try? self.coredataContext.save()
+
+                        let saveToInsulin = InsulinDistribution(context: self.coredataContext)
+                        saveToInsulin.bolus = (suggestion.insulin?.bolus ?? 0) as NSDecimalNumber?
+                        saveToInsulin.scheduledBasal = (suggestion.insulin?.scheduled_basal ?? 0) as NSDecimalNumber?
+                        saveToInsulin.tempBasal = (suggestion.insulin?.temp_basal ?? 0) as NSDecimalNumber?
+                        saveToInsulin.date = Date()
+                        try? self.coredataContext.save()
+                    }
+
                     promise(.success(suggestion))
                 } else {
                     promise(.success(nil))

+ 4 - 0
HbA1c+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(HbA1c) public class HbA1c: NSManagedObject {}

+ 15 - 0
HbA1c+CoreDataProperties.swift

@@ -0,0 +1,15 @@
+import CoreData
+import Foundation
+
+public extension HbA1c {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<HbA1c> {
+        NSFetchRequest<HbA1c>(entityName: "HbA1c")
+    }
+
+    @NSManaged var date: Date?
+    @NSManaged var hba1c: NSDecimalNumber?
+    @NSManaged var hba1c_1: NSDecimalNumber?
+    @NSManaged var hba1c_7: NSDecimalNumber?
+    @NSManaged var hba1c_30: NSDecimalNumber?
+    @NSManaged var hba1c_90: NSDecimalNumber?
+}

+ 4 - 0
InsulinDistribution+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(InsulinDistribution) public class InsulinDistribution: NSManagedObject {}

+ 14 - 0
InsulinDistribution+CoreDataProperties.swift

@@ -0,0 +1,14 @@
+import CoreData
+import Foundation
+
+public extension InsulinDistribution {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<InsulinDistribution> {
+        NSFetchRequest<InsulinDistribution>(entityName: "InsulinDistribution")
+    }
+
+    @NSManaged var bolus: NSDecimalNumber?
+    @NSManaged var tempBasal: NSDecimalNumber?
+    @NSManaged var scheduledBasal: NSDecimalNumber?
+    @NSManaged var date: Date?
+    @NSManaged var insulin: Oref0Suggestion?
+}

+ 4 - 0
Oref0Suggestion+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(Oref0Suggestion) public class Oref0Suggestion: NSManagedObject {}

+ 43 - 0
Oref0Suggestion+CoreDataProperties.swift

@@ -0,0 +1,43 @@
+import CoreData
+import Foundation
+
+public extension Oref0Suggestion {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<Oref0Suggestion> {
+        NSFetchRequest<Oref0Suggestion>(entityName: "Oref0Suggestion")
+    }
+
+    @NSManaged var computedTDD: NSSet?
+    @NSManaged var computedInsulinDistribution: NSSet?
+}
+
+// MARK: Generated accessors for computedTDD
+
+public extension Oref0Suggestion {
+    @objc(addComputedTDDObject:)
+    @NSManaged func addToComputedTDD(_ value: TDD)
+
+    @objc(removeComputedTDDObject:)
+    @NSManaged func removeFromComputedTDD(_ value: TDD)
+
+    @objc(addComputedTDD:)
+    @NSManaged func addToComputedTDD(_ values: NSSet)
+
+    @objc(removeComputedTDD:)
+    @NSManaged func removeFromComputedTDD(_ values: NSSet)
+}
+
+// MARK: Generated accessors for computedInsulinDistribution
+
+public extension Oref0Suggestion {
+    @objc(addComputedInsulinDistributionObject:)
+    @NSManaged func addToComputedInsulinDistribution(_ value: InsulinDistribution)
+
+    @objc(removeComputedInsulinDistributionObject:)
+    @NSManaged func removeFromComputedInsulinDistribution(_ value: InsulinDistribution)
+
+    @objc(addComputedInsulinDistribution:)
+    @NSManaged func addToComputedInsulinDistribution(_ values: NSSet)
+
+    @objc(removeComputedInsulinDistribution:)
+    @NSManaged func removeFromComputedInsulinDistribution(_ values: NSSet)
+}

+ 1 - 0
TDD+CoreDataProperties.swift

@@ -8,4 +8,5 @@ public extension TDD {
 
     @NSManaged var tdd: NSDecimalNumber?
     @NSManaged var timestamp: Date?
+    @NSManaged var computed: Oref0Suggestion?
 }