Loop share changes : get latest readings with timestamp > latest share. To make sure that's there's always 60 readings shared, the shared readings are stored in userdefaults (as array of dictionary), and will be reused next time that one or more new readings are shared. This will allow to update readings in coredata (due to smoothing algorithms), but still sharing the older values with Loop, and still making sure there's always 60 readings shared
This commit is contained in:
parent
efda0d9742
commit
e1a9c04eb5
|
@ -30,7 +30,7 @@ public class XDripClient {
|
|||
|
||||
private func fetchLastWithRetries(_ n: Int, remaining: Int, callback: @escaping (ClientError?, [Glucose]?) -> Void) {
|
||||
do {
|
||||
guard let sharedData = shared?.data(forKey: "latestReadings-widget") else {
|
||||
guard let sharedData = shared?.data(forKey: "latestReadings") else {
|
||||
throw ClientError.fetchError
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,6 @@ import Foundation
|
|||
enum ConstantsShareWithLoop {
|
||||
|
||||
/// maximum number of readings to share with Loop
|
||||
static let maxReadingsToShareWithLoop = 12
|
||||
|
||||
/// if the time between the last and last but one reading is less than minimiumTimeBetweenTwoReadingsInMinutes, then the reading will not be shared with loop - except if there's been a disconnect in between these two readings
|
||||
static let minimiumTimeBetweenTwoReadingsInMinutes = 4.75
|
||||
static let maxReadingsToShareWithLoop = 60
|
||||
|
||||
}
|
||||
|
|
|
@ -198,6 +198,13 @@ extension UserDefaults {
|
|||
/// timestamp of latest reading uploaded to Dexcom Share
|
||||
case timeStampLatestDexcomShareUploadedBgReading = "timeStampLatestDexcomShareUploadedBgReading"
|
||||
|
||||
// Loop
|
||||
/// dictionary representation of readings that were shared with Loop. This is not the json representation, it's an array of dictionary
|
||||
case readingsStoredInSharedUserDefaultsAsDictionary = "readingsStoredInSharedUserDefaultsAsDictionary"
|
||||
|
||||
/// timestamp lastest reading shared with Loop
|
||||
case timeStampLatestLoopSharedBgReading = "timeStampLatestLoopSharedBgReading"
|
||||
|
||||
// Trace
|
||||
/// should debug level logs be added in trace file or not, and also in NSLog
|
||||
case addDebugLevelLogsInTraceFileAndNSLog = "addDebugLevelLogsInTraceFileAndNSLog"
|
||||
|
@ -1081,6 +1088,28 @@ extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - ===== Loop Share Settings ======
|
||||
|
||||
/// dictionary representation of readings that were shared with Loop. This is not the json representation, it's an array of dictionary
|
||||
var readingsStoredInSharedUserDefaultsAsDictionary: [Dictionary<String, Any>]? {
|
||||
get {
|
||||
return object(forKey: Key.readingsStoredInSharedUserDefaultsAsDictionary.rawValue) as? [Dictionary<String, Any>]
|
||||
}
|
||||
set {
|
||||
set(newValue, forKey: Key.readingsStoredInSharedUserDefaultsAsDictionary.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// timestamp lastest reading uploaded to NightScout
|
||||
var timeStampLatestLoopSharedBgReading:Date? {
|
||||
get {
|
||||
return object(forKey: Key.timeStampLatestLoopSharedBgReading.rawValue) as? Date
|
||||
}
|
||||
set {
|
||||
set(newValue, forKey: Key.timeStampLatestLoopSharedBgReading.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ===== technical settings for testing ======
|
||||
|
||||
/// G6 factor 1
|
||||
|
|
|
@ -37,14 +37,18 @@ public class LoopManager:NSObject {
|
|||
// MARK: - public functions
|
||||
|
||||
/// share latest readings with Loop
|
||||
/// - lastConnectionStatusChangeTimeStamp : when was the last transmitter dis/reconnect - if nil then 1 1 1970 is used
|
||||
public func share(lastConnectionStatusChangeTimeStamp: Date?) {
|
||||
public func share() {
|
||||
|
||||
// unwrap sharedUserDefaults
|
||||
guard let sharedUserDefaults = sharedUserDefaults else {return}
|
||||
|
||||
// get last readings with calculated value, don't apply yet the filtering, we will first store for the widget unfiltered
|
||||
var lastReadings = bgReadingsAccessor.getLatestBgReadings(limit: ConstantsShareWithLoop.maxReadingsToShareWithLoop, fromDate: nil, forSensor: nil, ignoreRawData: true, ignoreCalculatedValue: false)
|
||||
// get last readings with calculated value
|
||||
let lastReadings = bgReadingsAccessor.getLatestBgReadings(limit: ConstantsShareWithLoop.maxReadingsToShareWithLoop, fromDate: UserDefaults.standard.timeStampLatestLoopSharedBgReading, forSensor: nil, ignoreRawData: true, ignoreCalculatedValue: false)
|
||||
|
||||
// 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>]()
|
||||
|
@ -52,30 +56,36 @@ public class LoopManager:NSObject {
|
|||
dictionary.append(reading.dictionaryRepresentationForDexcomShareUpload)
|
||||
}
|
||||
|
||||
// to json
|
||||
if let data = try? JSONSerialization.data(withJSONObject: dictionary) {
|
||||
// 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
|
||||
if let storedDictionary = UserDefaults.standard.readingsStoredInSharedUserDefaultsAsDictionary, storedDictionary.count > 0 {
|
||||
|
||||
let maxAmountsOfReadingsToAppend = ConstantsShareWithLoop.maxReadingsToShareWithLoop - dictionary.count
|
||||
|
||||
if maxAmountsOfReadingsToAppend > 0 {
|
||||
|
||||
let rangeToAppend = 0..<(min(storedDictionary.count, maxAmountsOfReadingsToAppend))
|
||||
|
||||
for value in storedDictionary[rangeToAppend] {
|
||||
|
||||
dictionary.append(value)
|
||||
|
||||
}
|
||||
|
||||
// share to userDefaults for widget
|
||||
if lastReadings.count > 0 {
|
||||
sharedUserDefaults.set(data, forKey: "latestReadings-widget")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// applying minimumTimeBetweenTwoReadingsInMinutes filter, for loop
|
||||
lastReadings = lastReadings.filter(minimumTimeBetweenTwoReadingsInMinutes: ConstantsShareWithLoop.minimiumTimeBetweenTwoReadingsInMinutes, lastConnectionStatusChangeTimeStamp: lastConnectionStatusChangeTimeStamp, timeStampLastProcessedBgReading: nil)
|
||||
|
||||
// if there's no readings, then no further processing
|
||||
if lastReadings.count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = try? JSONSerialization.data(withJSONObject: dictionary) else {
|
||||
return
|
||||
}
|
||||
|
||||
sharedUserDefaults.set(data, forKey: "latestReadings")
|
||||
|
||||
UserDefaults.standard.timeStampLatestLoopSharedBgReading = lastReadings.first!.timeStamp
|
||||
|
||||
UserDefaults.standard.readingsStoredInSharedUserDefaultsAsDictionary = dictionary
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -786,7 +786,7 @@ final class RootViewController: UIViewController {
|
|||
|
||||
watchManager?.processNewReading(lastConnectionStatusChangeTimeStamp: lastConnectionStatusChangeTimeStamp())
|
||||
|
||||
loopManager?.share(lastConnectionStatusChangeTimeStamp: lastConnectionStatusChangeTimeStamp())
|
||||
loopManager?.share()
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1092,7 +1092,7 @@ final class RootViewController: UIViewController {
|
|||
self.watchManager?.processNewReading(lastConnectionStatusChangeTimeStamp: self.lastConnectionStatusChangeTimeStamp())
|
||||
|
||||
// send also to loopmanager, not interesting for loop probably, but the data is also used for today widget
|
||||
self.loopManager?.share(lastConnectionStatusChangeTimeStamp: self.lastConnectionStatusChangeTimeStamp())
|
||||
self.loopManager?.share()
|
||||
|
||||
}
|
||||
|
||||
|
@ -1817,7 +1817,7 @@ extension RootViewController:NightScoutFollowerDelegate {
|
|||
bluetoothPeripheralManager?.sendLatestReading()
|
||||
|
||||
// send also to loopmanager, not interesting for loop probably, but the data is also used for today widget
|
||||
self.loopManager?.share(lastConnectionStatusChangeTimeStamp: lastConnectionStatusChangeTimeStamp())
|
||||
self.loopManager?.share()
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue