Bläddra i källkod

Remove externalInsulin event type by moving logic into NightscoutTreatment

Brian Wieder 2 år sedan
förälder
incheckning
9ccfe08d5a

+ 4 - 4
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -11,7 +11,7 @@ protocol CarbsStorage {
     func storeCarbs(_ carbs: [CarbsEntry])
     func syncDate() -> Date
     func recent() -> [CarbsEntry]
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
+    func nightscoutTretmentsNotUploaded() -> [NightscoutTreatment]
     func deleteCarbs(at date: Date)
 }
 
@@ -170,12 +170,12 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
         }
     }
 
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
-        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NigtscoutTreatment].self) ?? []
+    func nightscoutTretmentsNotUploaded() -> [NightscoutTreatment] {
+        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NightscoutTreatment].self) ?? []
 
         let eventsManual = recent().filter { $0.enteredBy == CarbsEntry.manual }
         let treatments = eventsManual.map {
-            NigtscoutTreatment(
+            NightscoutTreatment(
                 duration: nil,
                 rawDuration: nil,
                 rawRate: nil,

+ 7 - 7
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -15,7 +15,7 @@ protocol GlucoseStorage {
     func isGlucoseFresh() -> Bool
     func isGlucoseNotFlat() -> Bool
     func nightscoutGlucoseNotUploaded() -> [BloodGlucose]
-    func nightscoutCGMStateNotUploaded() -> [NigtscoutTreatment]
+    func nightscoutCGMStateNotUploaded() -> [NightscoutTreatment]
     var alarm: GlucoseAlarm? { get }
 }
 
@@ -82,7 +82,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
             debug(.deviceManager, "start storage cgmState")
             self.storage.transaction { storage in
                 let file = OpenAPS.Monitor.cgmState
-                var treatments = storage.retrieve(file, as: [NigtscoutTreatment].self) ?? []
+                var treatments = storage.retrieve(file, as: [NightscoutTreatment].self) ?? []
                 var updated = false
                 for x in glucose {
                     debug(.deviceManager, "storeGlucose \(x)")
@@ -104,7 +104,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
                     if let a = x.activationDate {
                         notes = "\(notes) activated on \(a)"
                     }
-                    let treatment = NigtscoutTreatment(
+                    let treatment = NightscoutTreatment(
                         duration: nil,
                         rawDuration: nil,
                         rawRate: nil,
@@ -112,7 +112,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
                         rate: nil,
                         eventType: .nsSensorChange,
                         createdAt: sessionStartDate,
-                        enteredBy: NigtscoutTreatment.local,
+                        enteredBy: NightscoutTreatment.local,
                         bolus: nil,
                         insulin: nil,
                         notes: notes,
@@ -209,9 +209,9 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
         return Array(Set(recentGlucose).subtracting(Set(uploaded)))
     }
 
-    func nightscoutCGMStateNotUploaded() -> [NigtscoutTreatment] {
-        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedCGMState, as: [NigtscoutTreatment].self) ?? []
-        let recent = storage.retrieve(OpenAPS.Monitor.cgmState, as: [NigtscoutTreatment].self) ?? []
+    func nightscoutCGMStateNotUploaded() -> [NightscoutTreatment] {
+        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedCGMState, as: [NightscoutTreatment].self) ?? []
+        let recent = storage.retrieve(OpenAPS.Monitor.cgmState, as: [NightscoutTreatment].self) ?? []
 
         return Array(Set(recent).subtracting(Set(uploaded)))
     }

+ 15 - 148
FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift

@@ -12,7 +12,7 @@ protocol PumpHistoryStorage {
     func storeEvents(_ events: [PumpHistoryEvent])
     func storeJournalCarbs(_ carbs: Int)
     func recent() -> [PumpHistoryEvent]
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
+    func nightscoutTreatmentsNotUploaded() -> [NightscoutTreatment]
     func saveCancelTempEvents()
     func deleteInsulin(at date: Date)
 }
@@ -210,163 +210,30 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
         }
     }
 
-    func determineBolusEventType(for event: PumpHistoryEvent) -> EventType {
-        if event.isExternalInsulin ?? false {
-            return .externalInsulin
-        }
-        return event.type
-    }
-
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
+    func nightscoutTreatmentsNotUploaded() -> [NightscoutTreatment] {
         let events = recent()
         guard !events.isEmpty else { return [] }
 
-        let temps: [NigtscoutTreatment] = events.reduce([]) { result, event in
-            var result = result
-            switch event.type {
-            case .tempBasal:
-                result.append(NigtscoutTreatment(
-                    duration: nil,
-                    rawDuration: nil,
-                    rawRate: event,
-                    absolute: event.rate,
-                    rate: event.rate,
-                    eventType: .nsTempBasal,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: nil,
-                    insulin: nil,
-                    notes: nil,
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                ))
-            case .tempBasalDuration:
-                if var last = result.popLast(), last.eventType == .nsTempBasal, last.createdAt == event.timestamp {
-                    last.duration = event.durationMin
-                    last.rawDuration = event
-                    result.append(last)
-                }
-            default: break
-            }
-            return result
-        }
+        var treatments: [NightscoutTreatment?] = []
 
-        let bolusesAndCarbs = events.compactMap { event -> NigtscoutTreatment? in
-            switch event.type {
-            case .bolus:
-                let eventType = determineBolusEventType(for: event)
-                return NigtscoutTreatment(
-                    duration: event.duration,
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: eventType,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: event,
-                    insulin: event.amount,
-                    notes: nil,
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                )
-            case .journalCarbs:
-                return NigtscoutTreatment(
-                    duration: nil,
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: .nsCarbCorrection,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: nil,
-                    insulin: nil,
-                    notes: nil,
-                    carbs: Decimal(event.carbInput ?? 0),
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                )
-            default: return nil
+        for i in 0 ..< events.count {
+            let event = events[i]
+            var nextEvent: PumpHistoryEvent?
+            if i + 1 < events.count {
+                nextEvent = events[i + 1]
             }
-        }
-
-        let misc = events.compactMap { event -> NigtscoutTreatment? in
-            switch event.type {
-            case .prime:
-                return NigtscoutTreatment(
-                    duration: event.duration,
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: .nsSiteChange,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: event,
-                    insulin: nil,
-                    notes: nil,
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                )
-            case .rewind:
-                return NigtscoutTreatment(
-                    duration: nil,
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: .nsInsulinChange,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: nil,
-                    insulin: nil,
-                    notes: nil,
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                )
-            case .pumpAlarm:
-                return NigtscoutTreatment(
-                    duration: 30, // minutes
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: .nsAnnouncement,
-                    createdAt: event.timestamp,
-                    enteredBy: NigtscoutTreatment.local,
-                    bolus: nil,
-                    insulin: nil,
-                    notes: "Alarm \(String(describing: event.note)) \(event.type)",
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    targetTop: nil,
-                    targetBottom: nil
-                )
-            default: return nil
+            if event.type == .tempBasal, nextEvent?.type == .tempBasalDuration {
+                treatments.append(NightscoutTreatment.from(event: event, tempBasalDuration: nextEvent))
+            } else {
+                treatments.append(NightscoutTreatment.from(event: event))
             }
         }
 
-        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NigtscoutTreatment].self) ?? []
+        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedPumphistory, as: [NightscoutTreatment].self) ?? []
 
-        let treatments = Array(Set([bolusesAndCarbs, temps, misc].flatMap { $0 }).subtracting(Set(uploaded)))
+        let treatmentsToUpload = Set(treatments.compactMap { $0 }).subtracting(Set(uploaded))
 
-        return treatments.sorted { $0.createdAt! > $1.createdAt! }
+        return treatmentsToUpload.sorted { $0.createdAt! > $1.createdAt! }
     }
 
     func saveCancelTempEvents() {

+ 4 - 4
FreeAPS/Sources/APS/Storage/TempTargetsStorage.swift

@@ -10,7 +10,7 @@ protocol TempTargetsStorage {
     func storeTempTargets(_ targets: [TempTarget])
     func syncDate() -> Date
     func recent() -> [TempTarget]
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
+    func nightscoutTretmentsNotUploaded() -> [NightscoutTreatment]
     func storePresets(_ targets: [TempTarget])
     func presets() -> [TempTarget]
     func current() -> TempTarget?
@@ -82,12 +82,12 @@ final class BaseTempTargetsStorage: TempTargetsStorage, Injectable {
         return last
     }
 
-    func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
-        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedTempTargets, as: [NigtscoutTreatment].self) ?? []
+    func nightscoutTretmentsNotUploaded() -> [NightscoutTreatment] {
+        let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedTempTargets, as: [NightscoutTreatment].self) ?? []
 
         let eventsManual = recent().filter { $0.enteredBy == TempTarget.manual }
         let treatments = eventsManual.map {
-            NigtscoutTreatment(
+            NightscoutTreatment(
                 duration: Int($0.duration),
                 rawDuration: nil,
                 rawRate: nil,

+ 139 - 4
FreeAPS/Sources/Models/NightscoutTreatment.swift

@@ -1,6 +1,13 @@
 import Foundation
 
-struct NigtscoutTreatment: JSON, Hashable, Equatable {
+func determineBolusEventType(for event: PumpHistoryEvent) -> EventType {
+    if event.isExternalInsulin ?? false {
+        return .nsExternalInsulin
+    }
+    return event.type
+}
+
+struct NightscoutTreatment: JSON, Hashable, Equatable {
     var duration: Int?
     var rawDuration: PumpHistoryEvent?
     var rawRate: PumpHistoryEvent?
@@ -21,18 +28,146 @@ struct NigtscoutTreatment: JSON, Hashable, Equatable {
 
     static let local = "Open-iAPS"
 
-    static let empty = NigtscoutTreatment(from: "{}")!
+    static let empty = NightscoutTreatment(from: "{}")!
 
-    static func == (lhs: NigtscoutTreatment, rhs: NigtscoutTreatment) -> Bool {
+    static func == (lhs: NightscoutTreatment, rhs: NightscoutTreatment) -> Bool {
         (lhs.createdAt ?? Date()) == (rhs.createdAt ?? Date())
     }
 
+    static func from(event: PumpHistoryEvent, tempBasalDuration: PumpHistoryEvent? = nil) -> Self? {
+        var basalDurationEvent: PumpHistoryEvent?
+        if tempBasalDuration != nil, tempBasalDuration?.timestamp == event.timestamp, event.type == .tempBasal,
+           tempBasalDuration?.type == .tempBasalDuration
+        {
+            basalDurationEvent = tempBasalDuration
+        }
+        switch event.type {
+        case .tempBasal:
+            return NightscoutTreatment(
+                duration: basalDurationEvent?.durationMin,
+                rawDuration: basalDurationEvent,
+                rawRate: event,
+                absolute: event.rate,
+                rate: event.rate,
+                eventType: .nsTempBasal,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: nil,
+                insulin: nil,
+                notes: nil,
+                carbs: nil,
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        case .bolus:
+            let eventType = determineBolusEventType(for: event)
+            return NightscoutTreatment(
+                duration: event.duration,
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: eventType,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: event,
+                insulin: event.amount,
+                notes: nil,
+                carbs: nil,
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        case .journalCarbs:
+            return NightscoutTreatment(
+                duration: nil,
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: .nsCarbCorrection,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: nil,
+                insulin: nil,
+                notes: nil,
+                carbs: Decimal(event.carbInput ?? 0),
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        case .prime:
+            return NightscoutTreatment(
+                duration: event.duration,
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: .nsSiteChange,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: event,
+                insulin: nil,
+                notes: nil,
+                carbs: nil,
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        case .rewind:
+            return NightscoutTreatment(
+                duration: nil,
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: .nsInsulinChange,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: nil,
+                insulin: nil,
+                notes: nil,
+                carbs: nil,
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        case .pumpAlarm:
+            return NightscoutTreatment(
+                duration: 30, // minutes
+                rawDuration: nil,
+                rawRate: nil,
+                absolute: nil,
+                rate: nil,
+                eventType: .nsAnnouncement,
+                createdAt: event.timestamp,
+                enteredBy: NightscoutTreatment.local,
+                bolus: nil,
+                insulin: nil,
+                notes: "Alarm \(String(describing: event.note)) \(event.type)",
+                carbs: nil,
+                fat: nil,
+                protein: nil,
+                targetTop: nil,
+                targetBottom: nil
+            )
+        default:
+            return nil
+        }
+    }
+
     func hash(into hasher: inout Hasher) {
         hasher.combine(createdAt ?? Date())
     }
 }
 
-extension NigtscoutTreatment {
+extension NightscoutTreatment {
     private enum CodingKeys: String, CodingKey {
         case duration
         case rawDuration = "raw_duration"

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

@@ -42,7 +42,6 @@ struct PumpHistoryEvent: JSON, Equatable {
 
 enum EventType: String, JSON {
     case bolus = "Bolus"
-    case externalInsulin = "External Insulin"
     case mealBolus = "Meal Bolus"
     case correctionBolus = "Correction Bolus"
     case snackBolus = "Snack Bolus"
@@ -65,6 +64,7 @@ enum EventType: String, JSON {
     case nsBatteryChange = "Pump Battery Change"
     case nsAnnouncement = "Announcement"
     case nsSensorChange = "Sensor Start"
+    case nsExternalInsulin = "External Insulin"
 }
 
 enum TempType: String, JSON {

+ 3 - 3
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -112,7 +112,7 @@ extension NightscoutAPI {
             ),
             URLQueryItem(
                 name: "find[enteredBy][$ne]",
-                value: NigtscoutTreatment.local.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
+                value: NightscoutTreatment.local.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
             )
         ]
         if let date = sinceDate {
@@ -213,7 +213,7 @@ extension NightscoutAPI {
             ),
             URLQueryItem(
                 name: "find[enteredBy][$ne]",
-                value: NigtscoutTreatment.local.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
+                value: NightscoutTreatment.local.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
             ),
             URLQueryItem(name: "find[duration][$exists]", value: "true")
         ]
@@ -278,7 +278,7 @@ extension NightscoutAPI {
             .eraseToAnyPublisher()
     }
 
-    func uploadTreatments(_ treatments: [NigtscoutTreatment]) -> AnyPublisher<Void, Swift.Error> {
+    func uploadTreatments(_ treatments: [NightscoutTreatment]) -> AnyPublisher<Void, Swift.Error> {
         var components = URLComponents()
         components.scheme = url.scheme
         components.host = url.host

+ 7 - 7
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -370,7 +370,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         var status: NightscoutStatus
 
         status = NightscoutStatus(
-            device: NigtscoutTreatment.local,
+            device: NightscoutTreatment.local,
             openaps: openapsStatus,
             pump: pump,
             uploader: uploader
@@ -399,11 +399,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     }
 
     func uploadPodAge() {
-        let uploadedPodAge = storage.retrieve(OpenAPS.Nightscout.uploadedPodAge, as: [NigtscoutTreatment].self) ?? []
+        let uploadedPodAge = storage.retrieve(OpenAPS.Nightscout.uploadedPodAge, as: [NightscoutTreatment].self) ?? []
         if let podAge = storage.retrieve(OpenAPS.Monitor.podAge, as: Date.self),
            uploadedPodAge.last?.createdAt == nil || podAge != uploadedPodAge.last!.createdAt!
         {
-            let siteTreatment = NigtscoutTreatment(
+            let siteTreatment = NightscoutTreatment(
                 duration: nil,
                 rawDuration: nil,
                 rawRate: nil,
@@ -411,7 +411,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
                 rate: nil,
                 eventType: .nsSiteChange,
                 createdAt: podAge,
-                enteredBy: NigtscoutTreatment.local,
+                enteredBy: NightscoutTreatment.local,
                 bolus: nil,
                 insulin: nil,
                 notes: nil,
@@ -529,7 +529,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
             startDate: now,
             mills: Int(now.timeIntervalSince1970) * 1000,
             units: nsUnits,
-            enteredBy: NigtscoutTreatment.local,
+            enteredBy: NightscoutTreatment.local,
             store: [defaultProfile: ps]
         )
 
@@ -579,7 +579,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     }
 
     private func uploadPumpHistory() {
-        uploadTreatments(pumpHistoryStorage.nightscoutTretmentsNotUploaded(), fileToSave: OpenAPS.Nightscout.uploadedPumphistory)
+        uploadTreatments(pumpHistoryStorage.nightscoutTreatmentsNotUploaded(), fileToSave: OpenAPS.Nightscout.uploadedPumphistory)
     }
 
     private func uploadCarbs() {
@@ -623,7 +623,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
-    private func uploadTreatments(_ treatments: [NigtscoutTreatment], fileToSave: String) {
+    private func uploadTreatments(_ treatments: [NightscoutTreatment], fileToSave: String) {
         guard !treatments.isEmpty, let nightscout = nightscoutAPI, isUploadEnabled else {
             return
         }