From 19993c34213a0250f00ab6eaff92d9e0ab69f3c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Sun, 18 Oct 2026 20:51:55 +0200 Subject: [PATCH] Show Loop IOB and COB on failed loops and hold the pump battery Loop uploads IOB and COB in records where the loop failed, so they are shown for those records too. The pump battery row keeps the last reading for up to an hour when a record leaves it out. Co-authored-by: Phil A <76601115+MtlPhil@users.noreply.github.com> --- .../Controllers/Nightscout/DeviceStatus.swift | 8 +++++ .../Nightscout/DeviceStatusLoop.swift | 30 +++++++++---------- .../ViewControllers/MainViewController.swift | 1 + 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/LoopFollow/Controllers/Nightscout/DeviceStatus.swift b/LoopFollow/Controllers/Nightscout/DeviceStatus.swift index ed672fa37..a4741037b 100644 --- a/LoopFollow/Controllers/Nightscout/DeviceStatus.swift +++ b/LoopFollow/Controllers/Nightscout/DeviceStatus.swift @@ -146,6 +146,14 @@ extension MainViewController { { infoManager.updateInfoData(type: .pumpBattery, value: String(format: "%.0f", pumpBatteryPercent) + "%", numericValue: pumpBatteryPercent) Observable.shared.pumpBatteryLevel.value = pumpBatteryPercent + latestPumpBatteryDate = Date() + } else if let lastPercent = Observable.shared.pumpBatteryLevel.value, + let lastDate = latestPumpBatteryDate, + Date().timeIntervalSince(lastDate) <= 60 * 60 + { + // Some records leave out the pump battery, and the level changes + // slowly, so the last reading is shown for up to an hour. + infoManager.updateInfoData(type: .pumpBattery, value: String(format: "%.0f", lastPercent) + "%", numericValue: lastPercent) } if let uploader = lastDeviceStatus?["uploader"] as? [String: AnyObject], diff --git a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift index 888c24a3c..8414b2457 100644 --- a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift +++ b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift @@ -17,6 +17,21 @@ extension MainViewController { let previousLastLoopTime = Observable.shared.previousAlertLastLoopTime.value ?? 0 let lastLoopTime = Observable.shared.alertLastLoopTime.value ?? 0 + // Loop reports IOB and COB even when the loop failed. + if let insulinMetric = InsulinMetric(from: lastLoopRecord["iob"], key: "iob") { + infoManager.updateInfoData(type: .iob, value: insulinMetric) + latestIOB = insulinMetric + Observable.shared.iobText.value = insulinMetric.formattedValue() + } + + if let cobMetric = CarbMetric(from: lastLoopRecord["cob"], key: "cob") { + infoManager.updateInfoData(type: .cob, value: cobMetric) + latestCOB = cobMetric + } + + Storage.shared.lastIOB.value = latestIOB?.value + Storage.shared.lastCOB.value = latestCOB?.value + if lastLoopRecord["failureReason"] != nil { Observable.shared.loopStatusText.value = "X" latestLoopStatusString = "X" @@ -52,19 +67,6 @@ extension MainViewController { Storage.shared.lastTargetLowMgdl.value = profileTargetLow?.doubleValue(for: .milligramsPerDeciliter) Storage.shared.lastTargetHighMgdl.value = profileTargetHigh?.doubleValue(for: .milligramsPerDeciliter) - // IOB - if let insulinMetric = InsulinMetric(from: lastLoopRecord["iob"], key: "iob") { - infoManager.updateInfoData(type: .iob, value: insulinMetric) - latestIOB = insulinMetric - Observable.shared.iobText.value = insulinMetric.formattedValue() - } - - // COB - if let cobMetric = CarbMetric(from: lastLoopRecord["cob"], key: "cob") { - infoManager.updateInfoData(type: .cob, value: cobMetric) - latestCOB = cobMetric - } - if let predictdata = lastLoopRecord["predicted"] as? [String: AnyObject], let prediction = predictdata["values"] as? [Double], let lastPrediction = prediction.last @@ -132,8 +134,6 @@ extension MainViewController { } // Live Activity storage - Storage.shared.lastIOB.value = latestIOB?.value - Storage.shared.lastCOB.value = latestCOB?.value if let predictdata = lastLoopRecord["predicted"] as? [String: AnyObject], let values = predictdata["values"] as? [Double] { diff --git a/LoopFollow/ViewControllers/MainViewController.swift b/LoopFollow/ViewControllers/MainViewController.swift index 5c6fb7e4f..98d1d9050 100644 --- a/LoopFollow/ViewControllers/MainViewController.swift +++ b/LoopFollow/ViewControllers/MainViewController.swift @@ -105,6 +105,7 @@ class MainViewController: UIViewController, UNUserNotificationCenterDelegate { var latestCOB: CarbMetric? var latestBasal = "" var latestPumpVolume: Double? + var latestPumpBatteryDate: Date? var latestIOB: InsulinMetric? var lastOverrideStartTime: TimeInterval = 0 var lastOverrideEndTime: TimeInterval = 0