@@ -10,79 +10,80 @@ import Foundation
1010import UIKit
1111
1212extension MainViewController {
13- // NS Override Response Processor
14- func processNSOverrides( entries: [ [ String : AnyObject ] ] ) {
13+
14+ func processNSOverrides( entries: [ [ String : AnyObject ] ] ) {
1515 overrideGraphData. removeAll ( )
16- var activeOverrideNote : String ? = nil
16+ var activeOverrideNote : String ?
17+
18+ let sorted = entries. sorted { lhs, rhs in
19+ guard
20+ let ls = ( lhs [ " timestamp " ] as? String ) ?? ( lhs [ " created_at " ] as? String ) ,
21+ let rs = ( rhs [ " timestamp " ] as? String ) ?? ( rhs [ " created_at " ] as? String ) ,
22+ let ld = NightscoutUtils . parseDate ( ls) ,
23+ let rd = NightscoutUtils . parseDate ( rs)
24+ else { return false }
25+ return ld < rd
26+ }
1727
1828 let now = Date ( ) . timeIntervalSince1970
19- let predictionLoadHours = UserDefaultsRepository . predictionToLoad. value
20- let predictionLoadSeconds = predictionLoadHours * 3600
21- let maxEndDate = now + predictionLoadSeconds
29+ let maxEndDate = now + UserDefaultsRepository. predictionToLoad. value * 3600
30+ let graphHorizon = dateTimeUtils. getTimeIntervalNHoursAgo ( N: 24 * UserDefaultsRepository. downloadDays. value)
2231
23- entries. reversed ( ) . enumerated ( ) . forEach { ( index, currentEntry) in
24- guard let dateStr = currentEntry [ " timestamp " ] as? String ?? currentEntry [ " created_at " ] as? String else { return }
25- guard let parsedDate = NightscoutUtils . parseDate ( dateStr) else { return }
32+ for i in 0 ..< sorted. count {
33+ let e = sorted [ i]
2634
27- var dateTimeStamp = parsedDate. timeIntervalSince1970
28- let graphHours = 24 * UserDefaultsRepository. downloadDays. value
29- if dateTimeStamp < dateTimeUtils. getTimeIntervalNHoursAgo ( N: graphHours) {
30- dateTimeStamp = dateTimeUtils. getTimeIntervalNHoursAgo ( N: graphHours)
31- }
32-
33- let multiplier = currentEntry [ " insulinNeedsScaleFactor " ] as? Double ?? 1.0
34-
35- var duration : Double = 5.0
36- if let _ = currentEntry [ " durationType " ] as? String , index == entries. count - 1 {
37- duration = dateTimeUtils. getNowTimeIntervalUTC ( ) - dateTimeStamp + ( 60 * 60 )
38- } else {
39- duration = ( currentEntry [ " duration " ] as? Double ?? 5.0 ) * 60
40- }
41-
42- if duration < 300 { return }
43-
44- let reason = currentEntry [ " reason " ] as? String ?? " "
35+ guard
36+ let dateStr = ( e [ " timestamp " ] as? String ) ?? ( e [ " created_at " ] as? String ) ,
37+ let startDate = NightscoutUtils . parseDate ( dateStr)
38+ else { continue }
4539
46- guard let enteredBy = currentEntry [ " enteredBy " ] as? String else {
47- return
48- }
40+ let start = max ( startDate. timeIntervalSince1970, graphHorizon)
41+ var end = start + ( e [ " duration " ] as? Double ?? 5 ) * 60 // seconds
4942
50- var range : [ Int ] = [ ]
51- if let ranges = currentEntry [ " correctionRange " ] as? [ Int ] , ranges. count == 2 {
52- range = ranges
53- } else {
54- let low = currentEntry [ " targetBottom " ] as? Int
55- let high = currentEntry [ " targetTop " ] as? Int
56- if ( low == nil && high != nil ) || ( low != nil && high == nil ) { return }
57- range = [ low ?? 0 , high ?? 0 ]
43+ if i + 1 < sorted. count,
44+ let nextDateStr = ( sorted [ i + 1 ] [ " timestamp " ] as? String ) ?? ( sorted [ i + 1 ] [ " created_at " ] as? String ) ,
45+ let nextStart = NightscoutUtils . parseDate ( nextDateStr) ?
46+ . timeIntervalSince1970
47+ {
48+ end = min ( end, nextStart - 60 ) // avoid overlapping overrides
5849 }
5950
60- // Limit displayed override duration to 'Hours of Prediction' after current time
61- var endDate = dateTimeStamp + duration
62- if endDate > maxEndDate {
63- endDate = maxEndDate
64- duration = endDate - dateTimeStamp
65- }
51+ end = min ( end, maxEndDate)
6652
67- if dateTimeStamp <= now && now < endDate {
68- activeOverrideNote = currentEntry [ " notes " ] as? String ?? currentEntry [ " reason " ] as? String
69- }
53+ if end - start < 300 { continue } // skip short overrides
7054
71- let dot = DataStructs . overrideStruct ( insulNeedsScaleFactor: multiplier, date: dateTimeStamp, endDate: endDate, duration: duration, correctionRange: range, enteredBy: enteredBy, reason: reason, sgv: - 20 )
55+ let dot = DataStructs . overrideStruct (
56+ insulNeedsScaleFactor: e [ " insulinNeedsScaleFactor " ] as? Double ?? 1 ,
57+ date: start,
58+ endDate: end,
59+ duration: end - start,
60+ correctionRange: {
61+ if let r = e [ " correctionRange " ] as? [ Int ] , r. count == 2 {
62+ return r
63+ }
64+ let lo = e [ " targetBottom " ] as? Int ?? 0
65+ let hi = e [ " targetTop " ] as? Int ?? 0
66+ return [ lo, hi]
67+ } ( ) ,
68+ enteredBy: e [ " enteredBy " ] as? String ?? " unknown " ,
69+ reason: e [ " reason " ] as? String ?? " " ,
70+ sgv: - 20
71+ )
7272 overrideGraphData. append ( dot)
73+
74+ if now >= start, now < end {
75+ activeOverrideNote = e [ " notes " ] as? String ?? e [ " reason " ] as? String
76+ }
7377 }
74-
75- Observable . shared. override. value = activeOverrideNote
7678
79+ Observable . shared. override. value = activeOverrideNote
7780 if ObservableUserDefaults . shared. device. value == " Trio " {
78- if let note = activeOverrideNote
79- {
81+ if let note = activeOverrideNote {
8082 infoManager. updateInfoData ( type: . override, value: note)
8183 } else {
8284 infoManager. clearInfoData ( type: . override)
8385 }
8486 }
85-
8687 if UserDefaultsRepository . graphOtherTreatments. value {
8788 updateOverrideGraph ( )
8889 }
0 commit comments