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

Merge branch 'dev' into Crowdin

Jon B.M 2 лет назад
Родитель
Сommit
eb72be757d

+ 6 - 1
Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22F82" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
+<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G90" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
     <entity name="BGaverages" representedClassName="BGaverages" syncable="YES" codeGenerationType="class">
     <entity name="BGaverages" representedClassName="BGaverages" syncable="YES" codeGenerationType="class">
         <attribute name="average" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <attribute name="average" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <attribute name="average_1" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <attribute name="average_1" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
@@ -38,6 +38,11 @@
         <attribute name="tempBasal" 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"/>
         <relationship name="insulin" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Oref0Suggestion" inverseName="computedInsulinDistribution" inverseEntity="Oref0Suggestion"/>
     </entity>
     </entity>
+    <entity name="LastLoop" representedClassName="LastLoop" syncable="YES" codeGenerationType="class">
+        <attribute name="cob" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="iob" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+    </entity>
     <entity name="LoopStatRecord" representedClassName="LoopStatRecord" syncable="YES" codeGenerationType="class">
     <entity name="LoopStatRecord" representedClassName="LoopStatRecord" syncable="YES" codeGenerationType="class">
         <attribute name="duration" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
         <attribute name="duration" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
         <attribute name="end" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <attribute name="end" optional="YES" attributeType="Date" usesScalarValueType="NO"/>

+ 9 - 0
FreeAPS/Sources/APS/APSManager.swift

@@ -711,6 +711,15 @@ final class BaseAPSManager: APSManager, Injectable {
 
 
             storage.save(enacted, as: OpenAPS.Enact.enacted)
             storage.save(enacted, as: OpenAPS.Enact.enacted)
 
 
+            // Save to CoreData also. TO DO: Remove the JSON saving after some testing.
+            coredataContext.perform {
+                let saveLastLoop = LastLoop(context: self.coredataContext)
+                saveLastLoop.iob = (enacted.iob ?? 0) as NSDecimalNumber
+                saveLastLoop.cob = (enacted.cob ?? 0) as NSDecimalNumber
+                saveLastLoop.timestamp = (enacted.timestamp ?? .distantPast) as Date
+                try? self.coredataContext.save()
+            }
+
             debug(.apsManager, "Suggestion enacted. Received: \(received)")
             debug(.apsManager, "Suggestion enacted. Received: \(received)")
             DispatchQueue.main.async {
             DispatchQueue.main.async {
                 self.broadcaster.notify(EnactedSuggestionObserver.self, on: .main) {
                 self.broadcaster.notify(EnactedSuggestionObserver.self, on: .main) {

+ 3 - 0
FreeAPS/Sources/Localizations/Main/en.lproj/Localizable.strings

@@ -962,6 +962,9 @@ Enact a temp Basal or a temp target */
 /* */
 /* */
 "Bolus failed" = "Bolus failed";
 "Bolus failed" = "Bolus failed";
 
 
+/* "Max Bolus Exceeded label" */
+"Max Bolus exceeded!" = "Max Bolus exceeded!";
+
 /* */
 /* */
 "Bolus failed or inaccurate. Check pump history before repeating." = "Bolus failed or inaccurate. Check pump history before repeating.";
 "Bolus failed or inaccurate. Check pump history before repeating." = "Bolus failed or inaccurate. Check pump history before repeating.";
 
 

+ 3 - 0
FreeAPS/Sources/Localizations/Main/sv.lproj/Localizable.strings

@@ -962,6 +962,9 @@ Enact a temp Basal or a temp target */
 /* */
 /* */
 "Bolus failed or inaccurate. Check pump history before repeating." = "Misslyckad eller felaktig bolus. Kontrollera pumpens historik innan du försöker igen.";
 "Bolus failed or inaccurate. Check pump history before repeating." = "Misslyckad eller felaktig bolus. Kontrollera pumpens historik innan du försöker igen.";
 
 
+/* "Max Bolus Exceeded label" */
+"Max Bolus exceeded!" = "Du kan inte ge mer än din maxinställning!";
+
 /* */
 /* */
 "Carbs" = "Kolhydrater";
 "Carbs" = "Kolhydrater";
 
 

+ 4 - 1
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -25,6 +25,7 @@ extension Bolus {
         @Published var expectedDelta: Decimal = 0
         @Published var expectedDelta: Decimal = 0
         @Published var minPredBG: Decimal = 0
         @Published var minPredBG: Decimal = 0
         @Published var units: GlucoseUnits = .mmolL
         @Published var units: GlucoseUnits = .mmolL
+        @Published var maxBolus: Decimal = 0
 
 
         var waitForSuggestionInitial: Bool = false
         var waitForSuggestionInitial: Bool = false
 
 
@@ -34,6 +35,7 @@ extension Bolus {
             units = settingsManager.settings.units
             units = settingsManager.settings.units
             percentage = settingsManager.settings.insulinReqPercentage
             percentage = settingsManager.settings.insulinReqPercentage
             threshold = provider.suggestion?.threshold ?? 0
             threshold = provider.suggestion?.threshold ?? 0
+            maxBolus = provider.pumpSettings().maxBolus
 
 
             if waitForSuggestionInitial {
             if waitForSuggestionInitial {
                 apsManager.determineBasal()
                 apsManager.determineBasal()
@@ -55,7 +57,7 @@ extension Bolus {
                 return
                 return
             }
             }
 
 
-            let maxAmount = Double(min(amount, provider.pumpSettings().maxBolus))
+            let maxAmount = Double(min(amount, maxBolus))
 
 
             unlockmanager.unlock()
             unlockmanager.unlock()
                 .sink { _ in } receiveValue: { [weak self] _ in
                 .sink { _ in } receiveValue: { [weak self] _ in
@@ -71,6 +73,7 @@ extension Bolus {
                 showModal(for: nil)
                 showModal(for: nil)
                 return
                 return
             }
             }
+            amount = min(amount, maxBolus)
 
 
             pumpHistoryStorage.storeEvents(
             pumpHistoryStorage.storeEvents(
                 [
                 [

+ 7 - 3
FreeAPS/Sources/Modules/Bolus/View/BolusRootView.swift

@@ -78,8 +78,10 @@ extension Bolus {
                     header: { Text("Bolus") }
                     header: { Text("Bolus") }
                     Section {
                     Section {
                         Button { state.add() }
                         Button { state.add() }
-                        label: { Text("Enact bolus") }
-                            .disabled(state.amount <= 0)
+                        label: { Text(!(state.amount > state.maxBolus) ? "Enact bolus" : "Max Bolus exceeded!") }
+                            .disabled(
+                                state.amount <= 0 || state.amount > state.maxBolus
+                            )
                     }
                     }
                     Section {
                     Section {
                         if waitForSuggestion {
                         if waitForSuggestion {
@@ -88,7 +90,9 @@ extension Bolus {
                         } else {
                         } else {
                             Button { isAddInsulinAlertPresented = true }
                             Button { isAddInsulinAlertPresented = true }
                             label: { Text("Add insulin without actually bolusing") }
                             label: { Text("Add insulin without actually bolusing") }
-                                .disabled(state.amount <= 0)
+                                .disabled(
+                                    state.amount <= 0 || state.amount > state.maxBolus
+                                )
                         }
                         }
                     }
                     }
                     .alert(isPresented: $isAddInsulinAlertPresented) {
                     .alert(isPresented: $isAddInsulinAlertPresented) {

+ 31 - 9
FreeAPS/Sources/Services/Calendar/CalendarManager.swift

@@ -1,4 +1,5 @@
 import Combine
 import Combine
+import CoreData
 import EventKit
 import EventKit
 import Swinject
 import Swinject
 
 
@@ -24,6 +25,8 @@ final class BaseCalendarManager: CalendarManager, Injectable {
         setupGlucose()
         setupGlucose()
     }
     }
 
 
+    let coredataContext = CoreDataStack.shared.persistentContainer.newBackgroundContext()
+
     func requestAccessIfNeeded() -> AnyPublisher<Bool, Never> {
     func requestAccessIfNeeded() -> AnyPublisher<Bool, Never> {
         Future { promise in
         Future { promise in
             let status = EKEventStore.authorizationStatus(for: .event)
             let status = EKEventStore.authorizationStatus(for: .event)
@@ -63,9 +66,30 @@ final class BaseCalendarManager: CalendarManager, Injectable {
         // create an event now
         // create an event now
         let event = EKEvent(eventStore: eventStore)
         let event = EKEvent(eventStore: eventStore)
 
 
+        // Calendar settings
+        let displeyCOBandIOB = settingsManager.settings.displayCalendarIOBandCOB
+        let displayEmojis = settingsManager.settings.displayCalendarEmojis
+
+        // Latest Loop data (from CoreData)
+        var freshLoop: Double = 20
+        var lastLoop = [LastLoop]()
+        if displeyCOBandIOB || displayEmojis {
+            coredataContext.performAndWait {
+                let requestLastLoop = LastLoop.fetchRequest() as NSFetchRequest<LastLoop>
+                let sortLoops = NSSortDescriptor(key: "timestamp", ascending: false)
+                requestLastLoop.sortDescriptors = [sortLoops]
+                requestLastLoop.fetchLimit = 1
+                try? lastLoop = coredataContext.fetch(requestLastLoop)
+            }
+            freshLoop = -1 * (lastLoop.first?.timestamp ?? .distantPast).timeIntervalSinceNow.minutes
+        }
+
         var glucoseIcon = "🟢"
         var glucoseIcon = "🟢"
-        glucoseIcon = Double(glucoseValue) <= Double(settingsManager.settings.low) ? "🔴" : glucoseIcon
-        glucoseIcon = Double(glucoseValue) >= Double(settingsManager.settings.high) ? "🟠" : glucoseIcon
+        if displayEmojis {
+            glucoseIcon = Double(glucoseValue) <= Double(settingsManager.settings.low) ? "🔴" : glucoseIcon
+            glucoseIcon = Double(glucoseValue) >= Double(settingsManager.settings.high) ? "🟠" : glucoseIcon
+            glucoseIcon = freshLoop > 15 ? "🚫" : glucoseIcon
+        }
 
 
         let glucoseText = glucoseFormatter
         let glucoseText = glucoseFormatter
             .string(from: Double(
             .string(from: Double(
@@ -79,18 +103,17 @@ final class BaseCalendarManager: CalendarManager, Injectable {
                     .string(from: Double(settingsManager.settings.units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
                     .string(from: Double(settingsManager.settings.units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
             } ?? "--"
             } ?? "--"
 
 
-        let fetchedSuggestion = storage.retrieve(OpenAPS.Enact.enacted, as: Suggestion.self)
-        let iobText = iobFormatter.string(from: (fetchedSuggestion?.iob ?? 0) as NSNumber) ?? ""
-        let cobText = cobFormatter.string(from: (fetchedSuggestion?.cob ?? 0) as NSNumber) ?? ""
+        let iobText = iobFormatter.string(from: (lastLoop.first?.iob ?? 0) as NSNumber) ?? ""
+        let cobText = cobFormatter.string(from: (lastLoop.first?.cob ?? 0) as NSNumber) ?? ""
 
 
-        var glucoseDisplayText = settingsManager.settings.displayCalendarEmojis ? glucoseIcon + " " : ""
+        var glucoseDisplayText = displayEmojis ? glucoseIcon + " " : ""
         glucoseDisplayText += glucoseText + " " + directionText + " " + deltaText
         glucoseDisplayText += glucoseText + " " + directionText + " " + deltaText
 
 
         var iobDisplayText = ""
         var iobDisplayText = ""
         var cobDisplayText = ""
         var cobDisplayText = ""
 
 
-        if settingsManager.settings.displayCalendarIOBandCOB {
-            if settingsManager.settings.displayCalendarEmojis {
+        if displeyCOBandIOB {
+            if displayEmojis {
                 iobDisplayText += "💉"
                 iobDisplayText += "💉"
                 cobDisplayText += "🥨"
                 cobDisplayText += "🥨"
             } else {
             } else {
@@ -99,7 +122,6 @@ final class BaseCalendarManager: CalendarManager, Injectable {
             }
             }
             iobDisplayText += " " + iobText
             iobDisplayText += " " + iobText
             cobDisplayText += " " + cobText
             cobDisplayText += " " + cobText
-
             event.location = iobDisplayText + " " + cobDisplayText
             event.location = iobDisplayText + " " + cobDisplayText
         }
         }