Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
eduardopietre 2022-05-11 15:26:56 -03:00
commit 9817210d66
3 changed files with 112 additions and 2 deletions

View File

@ -293,6 +293,11 @@ extension UserDefaults {
/// case smooth libre values
case smoothLibreValues = "smoothLibreValues"
/// to create artificial delay in readings stored in sharedUserDefaults for loop. Minutes - so that Loop receives more smoothed values.
///
/// Default value 0, if used then recommende value between 4 and 9
case loopDelay = "loopDelay"
/// used for Libre data parsing - only for Libre 1 or Libre 2 read via transmitter, ie full NFC block
case previousRawLibreValues = "previousRawLibreValues"
@ -401,6 +406,18 @@ extension UserDefaults {
set(newValue, forKey: Key.notificationInterval.rawValue)
}
}
/// to create artificial delay in readings stored in sharedUserDefaults for loop. Minutes - so that Loop receives more smoothed values.
///
/// Default value 0, if used then recommende value between 4 and 9
@objc dynamic var loopDelay: Int {
get {
return integer(forKey: Key.loopDelay.rawValue)
}
set {
set(newValue, forKey: Key.loopDelay.rawValue)
}
}
/// should reading be shown in app badge yes or no
@objc dynamic var showReadingInAppBadge: Bool {

View File

@ -44,13 +44,24 @@ public class LoopManager:NSObject {
guard let sharedUserDefaults = sharedUserDefaults else {return}
// get last readings with calculated value
let lastReadings = bgReadingsAccessor.getLatestBgReadings(limit: ConstantsShareWithLoop.maxReadingsToShareWithLoop, fromDate: UserDefaults.standard.timeStampLatestLoopSharedBgReading, forSensor: nil, ignoreRawData: true, ignoreCalculatedValue: false)
var lastReadings = bgReadingsAccessor.getLatestBgReadings(limit: ConstantsShareWithLoop.maxReadingsToShareWithLoop, fromDate: UserDefaults.standard.timeStampLatestLoopSharedBgReading, forSensor: nil, ignoreRawData: true, ignoreCalculatedValue: false)
// if needed, remove readings less than loopDelay minutes old
if UserDefaults.standard.loopDelay > 0 {
while lastReadings.count > 0 && lastReadings[0].timeStamp.addingTimeInterval(TimeInterval(minutes: Double(UserDefaults.standard.loopDelay))) > Date() {
lastReadings.remove(at: 0)
}
}
// if there's no readings, then no further processing
if lastReadings.count == 0 {
return
}
// convert to json Dexcom Share format
var dictionary = [Dictionary<String, Any>]()
for reading in lastReadings {
@ -59,6 +70,58 @@ public class LoopManager:NSObject {
representation["from"] = "xDrip"
dictionary.append(representation)
}
// now, if needed, increase the timestamp for each reading
if UserDefaults.standard.loopDelay > 0 {
// create new dictionary that will have the readings with timestamp increased
var newDictionary = [Dictionary<String, Any>]()
// iterate through dictionary
for reading in dictionary {
var readingTimeStamp: Date?
if let rawGlucoseStartDate = reading["DT"] as? String {
do {
readingTimeStamp = try self.parseTimestamp(rawGlucoseStartDate)
} catch {
}
}
if let readingTimeStamp = readingTimeStamp, let slopeOrdinal = reading["Trend"] as? Int, let value = reading["Value"] as? Double {
// create new date : original date + loopDelay
let newReadingTimeStamp = readingTimeStamp.addingTimeInterval(TimeInterval(minutes: Double(UserDefaults.standard.loopDelay)))
// ignore the reading if newReadingTimeStamp > now
if newReadingTimeStamp < Date() {
// this is for the json representation
let dateAsString = "/Date(" + Int64(floor(newReadingTimeStamp.toMillisecondsAsDouble() / 1000) * 1000).description + ")/"
// create new reading and append to new dictionary
let newReading: [String : Any] = [
"Trend" : slopeOrdinal,
"ST" : dateAsString,
"DT" : dateAsString,
"Value" : value,
"direction" : slopeOrdinal
]
newDictionary.append(newReading)
}
}
}
dictionary = newDictionary
}
// get Dictionary stored in UserDefaults from previous session
// append readings already stored in this storedDictionary so that we get dictionary filled with maxReadingsToShareWithLoop readings, if possible
@ -91,4 +154,13 @@ public class LoopManager:NSObject {
UserDefaults.standard.readingsStoredInSharedUserDefaultsAsDictionary = dictionary
}
private func parseTimestamp(_ timestamp: String) throws -> Date? {
let regex = try NSRegularExpression(pattern: "\\((.*)\\)")
if let match = regex.firstMatch(in: timestamp, range: NSMakeRange(0, timestamp.count)) {
let epoch = Double((timestamp as NSString).substring(with: match.range(at: 1)))! / 1000
return Date(timeIntervalSince1970: epoch)
}
return nil
}
}

View File

@ -11,6 +11,11 @@ fileprivate enum Setting:Int, CaseIterable {
/// case smooth libre values
case smoothLibreValues = 2
/// to create artificial delay in readings stored in sharedUserDefaults for loop. Minutes - so that Loop receives more smoothed values.
///
/// Default value 0, if used then recommende value between 4 and 9
case loopDelay = 3
}
struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
@ -42,6 +47,9 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .smoothLibreValues:
return Texts_SettingsView.smoothLibreValues
case .loopDelay:
return "Loop Delay"
}
}
@ -54,6 +62,9 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .NSLogEnabled, .OSLogEnabled, .smoothLibreValues:
return UITableViewCell.AccessoryType.none
case .loopDelay:
return UITableViewCell.AccessoryType.disclosureIndicator
}
}
@ -72,6 +83,9 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .smoothLibreValues:
return nil
case .loopDelay:
return UserDefaults.standard.loopDelay.description
}
}
@ -106,6 +120,9 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
})
case .loopDelay:
return nil
}
}
@ -123,6 +140,10 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .NSLogEnabled, .OSLogEnabled, .smoothLibreValues:
return .nothing
case .loopDelay:
return SettingsSelectedRowAction.askText(title: "Loop Delay", message: "Artificial delay in readings when sending to Loop (minutes) - 0 means no delay. Use maximum 10 minutes.", keyboardType: .numberPad, text: UserDefaults.standard.loopDelay.description, placeHolder: "0", actionTitle: nil, cancelTitle: nil, actionHandler: {(interval:String) in if let interval = Int(interval) {UserDefaults.standard.loopDelay = Int(interval)}}, cancelHandler: nil, inputValidator: nil)
}
}