Explorar o código

WiP..... carbs and profile basal in graph need fix for scaling

polscm32 %!s(int64=2) %!d(string=hai) anos
pai
achega
635244fb63

+ 5 - 2
FreeAPS/Sources/Models/BasalProfileEntry.swift

@@ -1,6 +1,7 @@
 import Foundation
 
-struct BasalProfileEntry: JSON, Equatable {
+struct BasalProfileEntry: JSON, Equatable, Identifiable {
+    let id: String?
     let start: String
     let minutes: Int
     let rate: Decimal
@@ -12,6 +13,7 @@ protocol BasalProfileObserver {
 
 extension BasalProfileEntry {
     private enum CodingKeys: String, CodingKey {
+        case id = "_id"
         case start
         case minutes
         case rate
@@ -19,10 +21,11 @@ extension BasalProfileEntry {
 
     init(from decoder: Decoder) throws {
         let container = try decoder.container(keyedBy: CodingKeys.self)
+        let id = try container.decode(String.self, forKey: .id)
         let start = try container.decode(String.self, forKey: .start)
         let minutes = try container.decode(Int.self, forKey: .minutes)
         let rate = try container.decode(Double.self, forKey: .rate).decimal ?? .zero
 
-        self = BasalProfileEntry(start: start, minutes: minutes, rate: rate)
+        self = BasalProfileEntry(id: id, start: start, minutes: minutes, rate: rate)
     }
 }

+ 1 - 1
FreeAPS/Sources/Modules/AutotuneConfig/AutotuneConfigStateModel.swift

@@ -67,7 +67,7 @@ extension AutotuneConfig {
                 let basals = autotunedBasals.basalProfile
                     .map { basal -> BasalProfileEntry in
                         BasalProfileEntry(
-                            start: String(basal.start.prefix(5)),
+                            id: "_id", start: String(basal.start.prefix(5)),
                             minutes: basal.minutes,
                             rate: basal.rate
                         )

+ 2 - 2
FreeAPS/Sources/Modules/BasalProfileEditor/BasalProfileEditorStateModel.swift

@@ -34,7 +34,7 @@ extension BasalProfileEditor {
                 let date = Date(timeIntervalSince1970: self.timeValues[item.timeIndex])
                 let minutes = Int(date.timeIntervalSince1970 / 60)
                 let rate = self.rateValues[item.rateIndex]
-                return BasalProfileEntry(start: fotmatter.string(from: date), minutes: minutes, rate: rate)
+                return BasalProfileEntry(id: "_id", start: fotmatter.string(from: date), minutes: minutes, rate: rate)
             }
 
             var profileWith24hours = profile.map(\.minutes)
@@ -66,7 +66,7 @@ extension BasalProfileEditor {
                 let date = Date(timeIntervalSince1970: self.timeValues[item.timeIndex])
                 let minutes = Int(date.timeIntervalSince1970 / 60)
                 let rate = self.rateValues[item.rateIndex]
-                return BasalProfileEntry(start: fotmatter.string(from: date), minutes: minutes, rate: rate)
+                return BasalProfileEntry(id: "_id", start: fotmatter.string(from: date), minutes: minutes, rate: rate)
             }
             provider.saveProfile(profile)
                 .receive(on: DispatchQueue.main)

+ 2 - 2
FreeAPS/Sources/Modules/Home/HomeProvider.swift

@@ -85,12 +85,12 @@ extension Home {
         func autotunedBasalProfile() -> [BasalProfileEntry] {
             storage.retrieve(OpenAPS.Settings.profile, as: Autotune.self)?.basalProfile
                 ?? storage.retrieve(OpenAPS.Settings.pumpProfile, as: Autotune.self)?.basalProfile
-                ?? [BasalProfileEntry(start: "00:00", minutes: 0, rate: 1)]
+                ?? [BasalProfileEntry(id: "_id", start: "00:00", minutes: 0, rate: 1)]
         }
 
         func basalProfile() -> [BasalProfileEntry] {
             storage.retrieve(OpenAPS.Settings.pumpProfile, as: Autotune.self)?.basalProfile
-                ?? [BasalProfileEntry(start: "00:00", minutes: 0, rate: 1)]
+                ?? [BasalProfileEntry(id: "_id", start: "00:00", minutes: 0, rate: 1)]
         }
     }
 }

+ 75 - 7
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView2.swift

@@ -8,15 +8,30 @@ struct MainChartView2: View {
     @Binding var highGlucose: Decimal
     @Binding var lowGlucose: Decimal
     @Binding var carbs: [CarbsEntry]
+    @Binding var basalProfile: [BasalProfileEntry]
 
     var body: some View {
         VStack(alignment: .center, spacing: 8, content: {
-            GlucoseChart(glucose: $glucose, screenHours: $screenHours, highGlucose: $highGlucose, lowGlucose: $lowGlucose)
-                .padding(.bottom, 20)
-            CarbsChart(carbs: $carbs, screenHours: $screenHours)
-                .padding(.bottom, 8)
+            ZStack {
+                GlucoseChart(glucose: $glucose, screenHours: $screenHours, highGlucose: $highGlucose, lowGlucose: $lowGlucose)
+                VStack {
+                    Spacer()
+                        .frame(height: 280)
+                    CarbsChart(carbs: $carbs, screenHours: $screenHours)
+                }
+            }
+//            GlucoseChart(glucose: $glucose, screenHours: $screenHours, highGlucose: $highGlucose, lowGlucose: $lowGlucose)
+//                .padding(.bottom, 20)
+//            CarbsChart(carbs: $carbs, screenHours: $screenHours)
+//                .padding(.bottom, 8)
+
             BasalChart(tempBasals: $tempBasals, screenHours: $screenHours)
                 .padding(.bottom, 8)
+
+//            ZStack {
+//                BasalChart(tempBasals: $tempBasals, basalProfile: $basalProfile, screenHours: $screenHours)
+//                BasalProfileChart(basalProfile: $basalProfile)
+//            }
             Legend()
         })
     }
@@ -44,6 +59,7 @@ struct GlucoseChart: View {
                     .lineStyle(StrokeStyle(lineWidth: 1, dash: [5]))
 
 //                MARK: TO DO -> at the moment this rule mark is not visible because the chart is not scrollable
+
                 if let currentTime = getCurrentTime() {
                     RuleMark(x: .value("Current Time", currentTime))
                         .foregroundStyle(Color.gray)
@@ -92,6 +108,7 @@ struct BasalChart: View {
     var body: some View {
         VStack {
             let filteredBasal: [PumpHistoryEvent] = filterBasalData(for: screenHours)
+
             Chart(filteredBasal) {
                 BarMark(
                     x: .value("Time", $0.timestamp),
@@ -101,8 +118,8 @@ struct BasalChart: View {
                 .cornerRadius(0)
             }
             .frame(height: 80)
-//            .rotationEffect(.degrees(180))
-//            .chartXAxis(.hidden)
+            //            .rotationEffect(.degrees(180))
+            //            .chartXAxis(.hidden)
             .chartYAxis(.hidden)
             .chartPlotStyle { plotArea in
                 plotArea.background(.blue.gradient.opacity(0.1))
@@ -122,21 +139,72 @@ struct BasalChart: View {
     }
 }
 
+struct BasalProfileChart: View {
+    @Binding var basalProfile: [BasalProfileEntry]
+    @Binding var screenHours: Int16
+
+    var body: some View {
+        let filteredBasalProfile: [BasalProfileEntry] = filterBasalProfileData(for: screenHours)
+
+        VStack {
+//            MARK: DOES NOT WORK
+
+//            filtering function seems not to work...displays nothing
+
+            Chart(filteredBasalProfile) {
+                LineMark(
+                    x: .value("start", $0.minutes),
+                    y: .value("rate", $0.rate)
+                ).foregroundStyle(Color.blue.gradient)
+            }
+        }
+    }
+
+    private func filterBasalProfileData(for hours: Int16) -> [BasalProfileEntry] {
+        guard hours > 0 else {
+            return basalProfile
+        }
+
+        let currentDate = Date()
+        let startDate = Calendar.current.date(byAdding: .hour, value: -Int(hours), to: currentDate) ?? currentDate
+
+        return basalProfile.filter { entry in
+            if let entryDate = dateFormatter.date(from: entry.start) {
+                return entryDate >= startDate
+            } else {
+                return false
+            }
+        }
+    }
+
+    private let dateFormatter: DateFormatter = {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "HH:mm:ss"
+        return formatter
+    }()
+}
+
 // MARK: COB
 
 struct CarbsChart: View {
     @Binding var carbs: [CarbsEntry]
     @Binding var screenHours: Int16
+    static var triangle: BasicChartSymbolShape { .triangle }
 
     var body: some View {
         VStack {
+//            MARK: DOES NOT WORK PROPERLY
+//            scaling is not correct because of swift charts automatic scaling...
+
             let filteredCarbs: [CarbsEntry] = filterCarbData(for: screenHours)
             Chart(filteredCarbs) {
                 PointMark(
                     x: .value("Time", $0.createdAt),
-                    y: .value("Value", 40)
+                    y: .value("Value", 10)
                 )
                 .foregroundStyle(Color.loopYellow.gradient)
+                .symbolSize(50)
+                .symbol(CarbsChart.triangle)
             }
             .frame(height: 80)
             .chartYAxis(.hidden)

+ 2 - 1
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -504,7 +504,8 @@ extension Home {
                     screenHours: $state.hours,
                     highGlucose: $state.highGlucose,
                     lowGlucose: $state.lowGlucose,
-                    carbs: $state.carbs
+                    carbs: $state.carbs,
+                    basalProfile: $state.basalProfile
                 )
             }
             .padding(.bottom)

+ 1 - 1
FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift

@@ -190,7 +190,7 @@ extension NightscoutConfig {
                                     areBasalsOK = false
                                 }
                                 return BasalProfileEntry(
-                                    start: basal.time,
+                                    id: "_id", start: basal.time,
                                     minutes: (basal.timeAsSeconds ?? self.offset(basal.time)) / 60,
                                     rate: basal.value
                                 ) }

+ 1 - 1
FreeAPS/Sources/Modules/PumpConfig/PumpConfigProvider.swift

@@ -16,7 +16,7 @@ extension PumpConfig {
 
         func basalProfile() -> [BasalProfileEntry] {
             storage.retrieve(OpenAPS.Settings.pumpProfile, as: Autotune.self)?.basalProfile
-                ?? [BasalProfileEntry(start: "00:00", minutes: 0, rate: 1)]
+                ?? [BasalProfileEntry(id: "_id", start: "00:00", minutes: 0, rate: 1)]
         }
 
         func pumpSettings() -> PumpSettings {