فهرست منبع

Rewrite of basal renedering

Jonas Björkert 1 سال پیش
والد
کامیت
1c36167bee
1فایلهای تغییر یافته به همراه95 افزوده شده و 97 حذف شده
  1. 95 97
      LoopFollow/Controllers/Nightscout/Treatments/Basals.swift

+ 95 - 97
LoopFollow/Controllers/Nightscout/Treatments/Basals.swift

@@ -7,44 +7,46 @@
 //
 
 import Foundation
+
 extension MainViewController {
     // NS Temp Basal Response Processor
     func processNSBasals(entries: [[String:AnyObject]]) {
         infoManager.clearInfoData(type: .basal)
 
-        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: Basal") }
-        // due to temp basal durations, we're going to destroy the array and load everything each cycle for the time being.
         basalData.removeAll()
-        
+
         var lastEndDot = 0.0
-        
+
+        let isoFormatter = ISO8601DateFormatter()
+        isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
+
         var tempArray = entries
         tempArray.reverse()
+
         for i in 0..<tempArray.count {
             let currentEntry = tempArray[i] as [String : AnyObject]?
-            var basalDate: String
-            if currentEntry?["timestamp"] != nil {
-                basalDate = currentEntry?["timestamp"] as! String
-            } else if currentEntry?["created_at"] != nil {
-                basalDate = currentEntry?["created_at"] as! String
+
+            var basalDateStr: String
+            if let ts = currentEntry?["timestamp"] as? String {
+                basalDateStr = ts
+            } else if let ca = currentEntry?["created_at"] as? String {
+                basalDateStr = ca
             } else {
                 continue
             }
-            var strippedZone = String(basalDate.dropLast())
-            strippedZone = strippedZone.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
-            let dateFormatter = DateFormatter()
-            dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
-            dateFormatter.locale = Locale(identifier: "en_US")
-            dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
-            guard let dateString = dateFormatter.date(from: strippedZone) else { continue }
-            let dateTimeStamp = dateString.timeIntervalSince1970
+
+            guard let dateParsed = isoFormatter.date(from: basalDateStr) else {
+                continue
+            }
+            let dateTimeStamp = dateParsed.timeIntervalSince1970
+
             guard let basalRate = currentEntry?["absolute"] as? Double else {
-                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "ERROR: Null Basal entry")}
+                if UserDefaultsRepository.debugLog.value {
+                    self.writeDebugLog(value: "ERROR: Null Basal entry")
+                }
                 continue
             }
-            
-            let midnightTime = dateTimeUtils.getTimeIntervalMidnightToday()
-            // Setting end dots
+
             var duration = 0.0
             if let durationValue = currentEntry?["duration"] as? Double {
                 duration = durationValue
@@ -52,42 +54,38 @@ extension MainViewController {
                 print("No Duration Found")
             }
 
-            // This adds scheduled basal wherever there is a break between temps. can't check the prior ending on the first item. it is 24 hours old, so it isn't important for display anyway
+            // *** Check for any gap since the previous entry
             if i > 0 {
                 let priorEntry = tempArray[i - 1] as [String : AnyObject]?
-                var priorBasalDate: String
-                if priorEntry?["timestamp"] != nil {
-                    priorBasalDate = priorEntry?["timestamp"] as! String
-                } else if currentEntry?["created_at"] != nil {
-                    priorBasalDate = priorEntry?["created_at"] as! String
+
+                var priorBasalDateStr: String
+                if let ts = priorEntry?["timestamp"] as? String {
+                    priorBasalDateStr = ts
+                } else if let ca = priorEntry?["created_at"] as? String {
+                    priorBasalDateStr = ca
                 } else {
                     continue
                 }
-                var priorStrippedZone = String(priorBasalDate.dropLast())
-                priorStrippedZone = priorStrippedZone.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
-                let priorDateFormatter = DateFormatter()
-                priorDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
-                priorDateFormatter.locale = Locale(identifier: "en_US")
-                priorDateFormatter.timeZone = TimeZone(abbreviation: "UTC")
-                guard let priorDateString = dateFormatter.date(from: priorStrippedZone) else { continue }
-                let priorDateTimeStamp = priorDateString.timeIntervalSince1970
+
+                guard let priorDateParsed = isoFormatter.date(from: priorBasalDateStr) else {
+                    continue
+                }
+                let priorDateTimeStamp = priorDateParsed.timeIntervalSince1970
                 let priorDuration = priorEntry?["duration"] as? Double ?? 0.0
+
                 // if difference between time stamps is greater than the duration of the last entry, there is a gap. Give a 15 second leeway on the timestamp
-                if Double( dateTimeStamp - priorDateTimeStamp ) > Double( (priorDuration * 60) + 15 ) {
-                    
+                if Double(dateTimeStamp - priorDateTimeStamp) > Double((priorDuration * 60) + 15) {
+
                     var scheduled = 0.0
-                    var midGap = false
+                    let midGap = false
                     var midGapTime: TimeInterval = 0
                     var midGapValue: Double = 0
-                    // cycle through basal profiles.
-                    // TODO figure out how to deal with profile changes that happen mid-gap
+
                     for b in 0..<self.basalScheduleData.count {
-                        
-                        if (priorDateTimeStamp + (priorDuration * 60)) >= basalScheduleData[b].date {
+                        let priorEnd = priorDateTimeStamp + (priorDuration * 60)
+                        if priorEnd >= basalScheduleData[b].date {
                             scheduled = basalScheduleData[b].basalRate
-                            
-                            // deal with mid-gap scheduled basal change
-                            // don't do it on the last scheudled basal entry
+
                             if b < self.basalScheduleData.count - 1 {
                                 if dateTimeStamp > self.basalScheduleData[b + 1].date {
                                     // midGap = true
@@ -96,106 +94,106 @@ extension MainViewController {
                                     midGapValue = self.basalScheduleData[b + 1].basalRate
                                 }
                             }
-                            
                         }
-                        
                     }
-                    
+
                     // Make the starting dot at the last ending dot
-                    let startDot = basalGraphStruct(basalRate: scheduled, date: Double(priorDateTimeStamp + (priorDuration * 60)))
+                    let startDot = basalGraphStruct(
+                        basalRate: scheduled,
+                        date: priorDateTimeStamp + (priorDuration * 60)
+                    )
                     basalData.append(startDot)
-                    
-                    
+
                     if midGap {
-                        // Make the ending dot at the new scheduled basal
-                        let endDot1 = basalGraphStruct(basalRate: scheduled, date: Double(midGapTime))
+                        // Make the ending dot at the old scheduled basal
+                        let endDot1 = basalGraphStruct(basalRate: scheduled, date: midGapTime)
                         basalData.append(endDot1)
                         // Make the starting dot at the scheduled Time
-                        let startDot2 = basalGraphStruct(basalRate: midGapValue, date: Double(midGapTime))
+                        let startDot2 = basalGraphStruct(basalRate: midGapValue, date: midGapTime)
                         basalData.append(startDot2)
                         // Make the ending dot at the new basal value
-                        let endDot2 = basalGraphStruct(basalRate: midGapValue, date: Double(dateTimeStamp))
+                        let endDot2 = basalGraphStruct(basalRate: midGapValue, date: dateTimeStamp)
                         basalData.append(endDot2)
-                        
                     } else {
                         // Make the ending dot at the new starting dot
-                        let endDot = basalGraphStruct(basalRate: scheduled, date: Double(dateTimeStamp))
+                        let endDot = basalGraphStruct(basalRate: scheduled, date: dateTimeStamp)
                         basalData.append(endDot)
                     }
-                    
-                    
                 }
             }
-            
+
             // Make the starting dot
-            let startDot = basalGraphStruct(basalRate: basalRate, date: Double(dateTimeStamp))
+            let startDot = basalGraphStruct(basalRate: basalRate, date: dateTimeStamp)
             basalData.append(startDot)
-            
+
             // Make the ending dot
-            // If it's the last one and has no duration, extend it for 30 minutes past the start. Otherwise set ending at duration
-            // duration is already set to 0 if there is no duration set on it.
-            //if i == tempArray.count - 1 && dateTimeStamp + duration <= dateTimeUtils.getNowTimeIntervalUTC() {
             if i == tempArray.count - 1 && duration == 0.0 {
+                // If it's the last one and has no duration
                 lastEndDot = dateTimeStamp + (30 * 60)
             } else {
                 lastEndDot = dateTimeStamp + (duration * 60)
             }
-            latestBasal = Localizer.formatToLocalizedString(basalRate, maxFractionDigits: 2, minFractionDigits: 0)
+            latestBasal = Localizer.formatToLocalizedString(basalRate,
+                                                            maxFractionDigits: 2,
+                                                            minFractionDigits: 0)
 
-            // Double check for overlaps of incorrectly ended TBRs and sent it to end when the next one starts if it finds a discrepancy
+            // *** Overlap check for next entry
             if i < tempArray.count - 1 {
                 let nextEntry = tempArray[i + 1] as [String : AnyObject]?
-                var nextBasalDate: String
-                if nextEntry?["timestamp"] != nil {
-                    nextBasalDate = nextEntry?["timestamp"] as! String
-                } else if currentEntry?["created_at"] != nil {
-                    nextBasalDate = nextEntry?["created_at"] as! String
+                var nextBasalDateStr: String
+                if let ts = nextEntry?["timestamp"] as? String {
+                    nextBasalDateStr = ts
+                } else if let ca = nextEntry?["created_at"] as? String {
+                    nextBasalDateStr = ca
                 } else {
                     continue
                 }
-                var nextStrippedZone = String(nextBasalDate.dropLast())
-                nextStrippedZone = nextStrippedZone.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
-                let nextDateFormatter = DateFormatter()
-                nextDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
-                nextDateFormatter.locale = Locale(identifier: "en_US")
-                nextDateFormatter.timeZone = TimeZone(abbreviation: "UTC")
-                guard let nextDateString = dateFormatter.date(from: nextStrippedZone) else { continue }
-                let nextDateTimeStamp = nextDateString.timeIntervalSince1970
+
+                guard let nextDateParsed = isoFormatter.date(from: nextBasalDateStr) else {
+                    continue
+                }
+                let nextDateTimeStamp = nextDateParsed.timeIntervalSince1970
                 if nextDateTimeStamp < (dateTimeStamp + (duration * 60)) {
                     lastEndDot = nextDateTimeStamp
                 }
             }
-            
-            let endDot = basalGraphStruct(basalRate: basalRate, date: Double(lastEndDot))
+
+            let endDot = basalGraphStruct(basalRate: basalRate, date: lastEndDot)
             basalData.append(endDot)
-            
-            
         }
-        
-        // If last  basal was prior to right now, we need to create one last scheduled entry
+
+        // If last basal was prior to right now, we need to create one last scheduled entry
         if lastEndDot <= dateTimeUtils.getNowTimeIntervalUTC() {
             var scheduled = 0.0
-            // cycle through basal profiles.
-            // TODO figure out how to deal with profile changes that happen mid-gap
             for b in 0..<self.basalProfile.count {
-                let scheduleTimeYesterday = self.basalProfile[b].timeAsSeconds + dateTimeUtils.getTimeIntervalMidnightYesterday()
-                let scheduleTimeToday = self.basalProfile[b].timeAsSeconds + dateTimeUtils.getTimeIntervalMidnightToday()
-                // check the prior temp ending to the profile seconds from midnight
+                let scheduleTimeToday = self.basalProfile[b].timeAsSeconds
+                + dateTimeUtils.getTimeIntervalMidnightToday()
                 if lastEndDot >= scheduleTimeToday {
                     scheduled = basalProfile[b].value
                 }
             }
-            
-            latestBasal = Localizer.formatToLocalizedString(scheduled, maxFractionDigits: 2, minFractionDigits: 0)
+
+            latestBasal = Localizer.formatToLocalizedString(
+                scheduled,
+                maxFractionDigits: 2,
+                minFractionDigits: 0
+            )
+
             // Make the starting dot at the last ending dot
-            let startDot = basalGraphStruct(basalRate: scheduled, date: Double(lastEndDot))
+            let startDot = basalGraphStruct(
+                basalRate: scheduled,
+                date: lastEndDot
+            )
             basalData.append(startDot)
-            
+
             // Make the ending dot 10 minutes after now
-            let endDot = basalGraphStruct(basalRate: scheduled, date: Double(Date().timeIntervalSince1970 + (60 * 10)))
+            let endDot = basalGraphStruct(
+                basalRate: scheduled,
+                date: Date().timeIntervalSince1970 + (60 * 10)
+            )
             basalData.append(endDot)
-            
         }
+
         if UserDefaultsRepository.graphBasal.value {
             updateBasalGraph()
         }