Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port over pump loss fix via LoopKit/Loop#1702 #277

Merged
merged 5 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 10 additions & 49 deletions FreeAPS/Sources/APS/DeviceDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = [
MockPumpManager.pluginIdentifier: MockPumpManager.self
]

// private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = staticPumpManagers.reduce(into: [:]) { map, Type in
// map[Type.managerIdentifier] = Type
// }

private let accessLock = NSRecursiveLock(label: "BaseDeviceDataManager.accessLock")

final class BaseDeviceDataManager: DeviceDataManager, Injectable {
Expand Down Expand Up @@ -78,7 +74,8 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
didSet {
pumpManager?.pumpManagerDelegate = self
pumpManager?.delegateQueue = processQueue
UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue
rawPumpManager = pumpManager?.rawValue
UserDefaults.standard.clearLegacyPumpManagerRawValue()
if let pumpManager = pumpManager {
pumpDisplayState.value = PumpDisplayState(name: pumpManager.localizedTitle, image: pumpManager.smallImage)
pumpName.send(pumpManager.localizedTitle)
Expand All @@ -105,6 +102,8 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
}
}

@PersistedProperty(key: "PumpManagerState") var rawPumpManager: PumpManager.RawValue?

var bluetoothManager: BluetoothStateManager { bluetoothProvider }

var hasBLEHeartbeat: Bool {
Expand All @@ -123,7 +122,11 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
}

func setupPumpManager() {
pumpManager = UserDefaults.standard.pumpManagerRawValue.flatMap { pumpManagerFromRawValue($0) }
if let pumpManagerRawValue = rawPumpManager ?? UserDefaults.standard.legacyPumpManagerRawValue {
pumpManager = pumpManagerFromRawValue(pumpManagerRawValue)
} else {
pumpManager = nil
}
}

func createBolusProgressReporter() -> DoseProgressReporter? {
Expand Down Expand Up @@ -163,20 +166,6 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
self.updateUpdateFinished(true)
}
}

// pumpUpdateCancellable = Future<Bool, Never> { [unowned self] promise in
// pumpUpdatePromise = promise
// debug(.deviceManager, "Waiting for pump update and loop recommendation")
// processQueue.safeSync {
// pumpManager.ensureCurrentPumpData { _ in
// debug(.deviceManager, "Pump data updated.")
// }
// }
// }
// .timeout(30, scheduler: processQueue)
// .replaceError(with: false)
// .replaceEmpty(with: false)
// .sink(receiveValue: updateUpdateFinished)
}

private func updateUpdateFinished(_ recommendsLoop: Bool) {
Expand All @@ -186,11 +175,6 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
warning(.deviceManager, "Loop recommendation time out or got error. Trying to loop right now.")
}

// directly in loop() function
// guard !loopInProgress else {
// warning(.deviceManager, "Loop already in progress. Skip recommendation.")
// return
// }
self.recommendsLoop.send()
}

Expand Down Expand Up @@ -319,7 +303,7 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
}

func pumpManagerDidUpdateState(_ pumpManager: PumpManager) {
UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue
rawPumpManager = pumpManager.rawValue
if self.pumpManager == nil, let newPumpManager = pumpManager as? PumpManagerUI {
self.pumpManager = newPumpManager
}
Expand Down Expand Up @@ -537,29 +521,6 @@ extension BaseDeviceDataManager: DeviceManagerDelegate {

func recordRetractedAlert(_: Alert, at _: Date) {}

// func scheduleNotification(
// for _: DeviceManager,
// identifier: String,
// content: UNNotificationContent,
// trigger: UNNotificationTrigger?
// ) {
// let request = UNNotificationRequest(
// identifier: identifier,
// content: content,
// trigger: trigger
// )
//
// DispatchQueue.main.async {
// UNUserNotificationCenter.current().add(request)
// }
// }
//
// func clearNotification(for _: DeviceManager, identifier: String) {
// DispatchQueue.main.async {
// UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
// }
// }

func removeNotificationRequests(for _: DeviceManager, identifiers: [String]) {
DispatchQueue.main.async {
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
Expand Down
18 changes: 2 additions & 16 deletions FreeAPS/Sources/APS/Extensions/PumpManagerExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import LoopKit
import LoopKitUI

extension PumpManager {
typealias RawValue = [String: Any]

var rawValue: [String: Any] {
[
"managerIdentifier": pluginIdentifier, // "managerIdentifier": type(of: self).managerIdentifier,
Expand All @@ -11,14 +13,6 @@ extension PumpManager {
}

extension PumpManagerUI {
// static func setupViewController() -> PumpManagerSetupViewController & UIViewController & CompletionNotifying {
// setupViewController(
// insulinTintColor: .accentColor,
// guidanceColors: GuidanceColors(acceptable: .green, warning: .orange, critical: .red),
// allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev]
// )
// }

func settingsViewController(
bluetoothProvider: BluetoothProvider,
pumpManagerOnboardingDelegate: PumpManagerOnboardingDelegate?
Expand All @@ -32,14 +26,6 @@ extension PumpManagerUI {
vc.pumpManagerOnboardingDelegate = pumpManagerOnboardingDelegate
return vc
}

// func settingsViewController() -> UIViewController & CompletionNotifying {
// settingsViewController(
// insulinTintColor: .accentColor,
// guidanceColors: GuidanceColors(acceptable: .green, warning: .orange, critical: .red),
// allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev]
// )
// }
}

protocol PumpSettingsBuilder {
Expand Down
29 changes: 19 additions & 10 deletions FreeAPS/Sources/APS/Extensions/UserDefaultsExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,10 @@ import RileyLinkKit

extension UserDefaults {
private enum Key: String {
case pumpManagerRawValue = "com.rileylink.PumpManagerRawValue"
case legacyPumpManagerRawValue = "com.rileylink.PumpManagerRawValue"
case rileyLinkConnectionManagerState = "com.rileylink.RileyLinkConnectionManagerState"
}

var pumpManagerRawValue: PumpManager.RawStateValue? {
get {
dictionary(forKey: Key.pumpManagerRawValue.rawValue)
}
set {
set(newValue, forKey: Key.pumpManagerRawValue.rawValue)
}
case legacyPumpManagerState = "com.loopkit.Loop.PumpManagerState"
case legacyCGMManagerState = "com.loopkit.Loop.CGMManagerState"
}

var rileyLinkConnectionManagerState: RileyLinkConnectionState? {
Expand All @@ -30,4 +23,20 @@ extension UserDefaults {
set(newValue?.rawValue, forKey: Key.rileyLinkConnectionManagerState.rawValue)
}
}

var legacyPumpManagerRawValue: PumpManager.RawValue? {
dictionary(forKey: Key.legacyPumpManagerRawValue.rawValue)
}

func clearLegacyPumpManagerRawValue() {
set(nil, forKey: Key.legacyPumpManagerRawValue.rawValue)
}

var legacyCGMManagerRawValue: CGMManager.RawValue? {
dictionary(forKey: Key.legacyCGMManagerState.rawValue)
}

func clearLegacyCGMManagerRawValue() {
set(nil, forKey: Key.legacyCGMManagerState.rawValue)
}
}
1 change: 1 addition & 0 deletions FreeAPS/Sources/APS/FetchGlucoseManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
var cgmManager: CGMManagerUI? {
didSet {
rawCGMManager = cgmManager?.rawValue
UserDefaults.standard.clearLegacyCGMManagerRawValue()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import Foundation
self.key = key

let documents: URL

guard let localDocuments = try? FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
Expand Down
16 changes: 16 additions & 0 deletions FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ extension Settings {
func hideSettingsModal() {
hideModal()
}
// Commenting this out for now, as not needed and possibly dangerous for users to be able to nuke their pump pairing informations via the debug menu
// Leaving it in here, as it may be a handy functionality for further testing or developers.
// See https://github.com/nightscout/Trio/pull/277 for more information
//
// func resetLoopDocuments() {
// guard let localDocuments = try? FileManager.default.url(
// for: .documentDirectory,
// in: .userDomainMask,
// appropriateFor: nil,
// create: true
// ) else {
// preconditionFailure("Could not get a documents directory URL.")
// }
// let storageURL = localDocuments.appendingPathComponent("PumpManagerState" + ".plist")
// try? FileManager.default.removeItem(at: storageURL)
// }
}
}

Expand Down
10 changes: 10 additions & 0 deletions FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ extension Settings {
.frame(maxWidth: .infinity, alignment: .trailing)
.buttonStyle(.borderedProminent)
}
// Commenting this out for now, as not needed and possibly dangerous for users to be able to nuke their pump pairing informations via the debug menu
// Leaving it in here, as it may be a handy functionality for further testing or developers.
// See https://github.com/nightscout/Trio/pull/277 for more information
//
// HStack {
// Text("Delete Stored Pump State Binary Files")
// Button("Delete") { state.resetLoopDocuments() }
// .frame(maxWidth: .infinity, alignment: .trailing)
// .buttonStyle(.borderedProminent)
// }
}
Group {
Text("Preferences")
Expand Down