Ivan Valkou пре 5 година
родитељ
комит
accb135546

+ 1 - 0
FreeAPS/Resources/json/defaults/nightscout/uploaded-carbs.json

@@ -0,0 +1 @@
+[]

+ 1 - 0
FreeAPS/Sources/APS/OpenAPS/Constants.swift

@@ -69,6 +69,7 @@ extension OpenAPS {
 
     enum Nightscout {
         static let uploadedPumphistory = "upload/uploaded-pumphistory.json"
+        static let uploadedCarbs = "upload/uploaded-carbs.json"
     }
 
     enum FreeAPS {

+ 38 - 1
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -2,14 +2,20 @@ import Foundation
 import SwiftDate
 import Swinject
 
+protocol CarbsObserver {
+    func carbsDidUpdate(_ carbs: [CarbsEntry])
+}
+
 protocol CarbsStorage {
     func storeCarbs(_ carbs: [CarbsEntry])
     func syncDate() -> Date
+    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
 }
 
 final class BaseCarbsStorage: CarbsStorage, Injectable {
     private let processQueue = DispatchQueue(label: "BaseCarbsStorage.processQueue")
     @Injected() private var storage: FileStorage!
+    @Injected() private var broadcaster: Broadcaster!
 
     init(resolver: Resolver) {
         injectServices(resolver)
@@ -18,13 +24,17 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
     func storeCarbs(_ carbs: [CarbsEntry]) {
         processQueue.sync {
             let file = OpenAPS.Monitor.carbHistory
+            var uniqEvents: [CarbsEntry] = []
             try? self.storage.transaction { storage in
                 try storage.append(carbs, to: file, uniqBy: \.createdAt)
-                let uniqEvents = try storage.retrieve(file, as: [CarbsEntry].self)
+                uniqEvents = try storage.retrieve(file, as: [CarbsEntry].self)
                     .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
                     .sorted { $0.createdAt > $1.createdAt }
                 try storage.save(Array(uniqEvents), as: file)
             }
+            broadcaster.notify(CarbsObserver.self, on: processQueue) {
+                $0.carbsDidUpdate(uniqEvents)
+            }
         }
     }
 
@@ -36,4 +46,31 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
         }
         return recent.createdAt.addingTimeInterval(-6.minutes.timeInterval)
     }
+
+    func recent() -> [CarbsEntry] {
+        (try? storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self))?.reversed() ?? []
+    }
+
+    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
+        let uploaded = (try? storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NigtscoutTreatment].self)) ?? []
+
+        let eventsManual = recent().filter { $0.enteredBy == CarbsEntry.manual }
+        let treatments = eventsManual.map {
+            NigtscoutTreatment(
+                duration: nil,
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: .nsCarbCorrection,
+                createdAt: $0.createdAt,
+                entededBy: CarbsEntry.manual,
+                bolus: nil,
+                insulin: nil,
+                notes: nil,
+                carbs: $0.carbs
+            )
+        }
+        return Array(Set(treatments).subtracting(Set(uploaded)))
+    }
 }

+ 17 - 3
FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift

@@ -208,7 +208,7 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
             return result
         }
 
-        let boluses = events.compactMap { event -> NigtscoutTreatment? in
+        let bolusesAndCarbs = events.compactMap { event -> NigtscoutTreatment? in
             switch event.type {
             case .bolus:
                 return NigtscoutTreatment(
@@ -225,15 +225,29 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                     notes: nil,
                     carbs: nil
                 )
+            case .journalCarbs:
+                return NigtscoutTreatment(
+                    duration: nil,
+                    rawDuration: nil,
+                    rawRate: nil,
+                    absolute: nil,
+                    rate: nil,
+                    eventType: .nsCarbCorrection,
+                    createdAt: event.timestamp,
+                    entededBy: NigtscoutTreatment.local,
+                    bolus: nil,
+                    insulin: nil,
+                    notes: nil,
+                    carbs: Decimal(event.carbInput ?? 0)
+                )
             default: return nil
             }
         }
 
         let uploaded = (try? storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NigtscoutTreatment].self)) ?? []
 
-        let treatments = Array(Set([boluses, temps].flatMap { $0 }).subtracting(Set(uploaded)))
+        let treatments = Array(Set([bolusesAndCarbs, temps].flatMap { $0 }).subtracting(Set(uploaded)))
 
         return treatments.sorted { $0.createdAt! > $1.createdAt! }
-//            .filter { $0.createdAt!.addingTimeInterval(3.hours.timeInterval) > Date() }
     }
 }

+ 1 - 0
FreeAPS/Sources/Models/PumpHistoryEvent.swift

@@ -27,6 +27,7 @@ enum PumpHistoryEventType: String, JSON {
     case journalCarbs = "JournalEntryMealMarker"
 
     case nsTempBasal = "Temp Basal"
+    case nsCarbCorrection = "Carb Correction"
 }
 
 enum TempType: String, JSON {

+ 10 - 3
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -40,6 +40,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
     private func subscribe() {
         broadcaster.register(PumpHistoryObserver.self, observer: self)
+        broadcaster.register(CarbsObserver.self, observer: self)
     }
 
     func fetchGlucose() -> AnyPublisher<Void, Never> {
@@ -101,7 +102,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
     private func uploadStatus() {}
 
-    private func uploadPumpHistory(_ treatments: [NigtscoutTreatment]) {
+    private func uploadPumpHistory(_ treatments: [NigtscoutTreatment], fileToSave: String) {
         guard !treatments.isEmpty, let nightscout = nightscoutAPI else {
             return
         }
@@ -111,7 +112,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
                 .sink { completion in
                     switch completion {
                     case .finished:
-                        try? self.storage.save(treatments, as: OpenAPS.Nightscout.uploadedPumphistory)
+                        try? self.storage.save(treatments, as: fileToSave)
                     case let .failure(error):
                         debug(.nightscout, error.localizedDescription)
                     }
@@ -123,6 +124,12 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
 extension BaseNightscoutManager: PumpHistoryObserver {
     func pumpHistoryDidUpdate(_: [PumpHistoryEvent]) {
-        uploadPumpHistory(pumpHistoryStorage.nightscoutTretmentsNotUploaded())
+        uploadPumpHistory(pumpHistoryStorage.nightscoutTretmentsNotUploaded(), fileToSave: OpenAPS.Nightscout.uploadedPumphistory)
+    }
+}
+
+extension BaseNightscoutManager: CarbsObserver {
+    func carbsDidUpdate(_: [CarbsEntry]) {
+        uploadPumpHistory(carbsStorage.nightscoutTretmentsNotUploaded(), fileToSave: OpenAPS.Nightscout.uploadedCarbs)
     }
 }