From 6bd341686958d4029317d1c3475126e7eb95903b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Thu, 9 Jul 2026 00:31:27 +0200 Subject: [PATCH 1/2] Format Loop's recommended bolus with InsulinMetric The Loop device status parser formatted Rec. Bolus with a hardcoded String(format: "%.2fU"), while the OpenAPS/Trio parser routed the value through InsulinMetric. The same recommendation rendered as "0.00U" on a Loop URL and "0" on a Trio URL. Use InsulinMetric on both paths. --- LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift index 771fdc68d..ba28fdbfa 100644 --- a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift +++ b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift @@ -100,10 +100,9 @@ extension MainViewController { infoManager.clearInfoData(type: .minMax) updatePredictionGraph() } - if let recBolus = lastLoopRecord["recommendedBolus"] as? Double { - let formattedRecBolus = String(format: "%.2fU", recBolus) - infoManager.updateInfoData(type: .recBolus, value: formattedRecBolus) - Observable.shared.deviceRecBolus.value = recBolus + if let recBolus = InsulinMetric(from: lastLoopRecord, key: "recommendedBolus") { + infoManager.updateInfoData(type: .recBolus, value: recBolus) + Observable.shared.deviceRecBolus.value = recBolus.value } if let loopStatus = lastLoopRecord["recommendedTempBasal"] as? [String: AnyObject] { if let tempBasalTime = formatter.date(from: (loopStatus["timestamp"] as! String))?.timeIntervalSince1970 { From c0d96438df15b634309d2bff98d1db9e372e2c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Thu, 9 Jul 2026 00:36:01 +0200 Subject: [PATCH 2/2] Format Rec. Bolus with the pump's bolus increment Rec. Bolus was formatted two different ways: the Loop parser used a hardcoded String(format: "%.2fU"), while the OpenAPS/Trio parser went through InsulinMetric, which drops to one fraction digit below 10 U. The same recommendation rendered as "0.00U" on a Loop URL and "0" on a Trio URL. Both parsers now use InsulinFormatter, which derives its fraction digits from the pump's reported bolusIncrement, so the value is shown at the precision the pump can actually deliver. The unit suffix is dropped to match the other insulin rows in the info table. Clear the info row and deviceRecBolus when the device status carries no recommendation, so a stale value can't linger in the info table, the Rec. Bolus alarm condition, or the Live Activity. --- LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift | 9 ++++++--- .../Controllers/Nightscout/DeviceStatusOpenAPS.swift | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift index ba28fdbfa..c825582ba 100644 --- a/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift +++ b/LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift @@ -100,9 +100,12 @@ extension MainViewController { infoManager.clearInfoData(type: .minMax) updatePredictionGraph() } - if let recBolus = InsulinMetric(from: lastLoopRecord, key: "recommendedBolus") { - infoManager.updateInfoData(type: .recBolus, value: recBolus) - Observable.shared.deviceRecBolus.value = recBolus.value + if let recBolus = lastLoopRecord["recommendedBolus"] as? Double { + infoManager.updateInfoData(type: .recBolus, value: InsulinFormatter.shared.string(recBolus)) + Observable.shared.deviceRecBolus.value = recBolus + } else { + infoManager.clearInfoData(type: .recBolus) + Observable.shared.deviceRecBolus.value = nil } if let loopStatus = lastLoopRecord["recommendedTempBasal"] as? [String: AnyObject] { if let tempBasalTime = formatter.date(from: (loopStatus["timestamp"] as! String))?.timeIntervalSince1970 { diff --git a/LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift b/LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift index ca8338a47..ac84ceb85 100644 --- a/LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift +++ b/LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift @@ -107,10 +107,11 @@ extension MainViewController { } // Recommended Bolus - if let rec = InsulinMetric(from: lastLoopRecord, key: "recommendedBolus") { - infoManager.updateInfoData(type: .recBolus, value: rec) - Observable.shared.deviceRecBolus.value = rec.value + if let rec = lastLoopRecord["recommendedBolus"] as? Double { + infoManager.updateInfoData(type: .recBolus, value: InsulinFormatter.shared.string(rec)) + Observable.shared.deviceRecBolus.value = rec } else { + infoManager.clearInfoData(type: .recBolus) Observable.shared.deviceRecBolus.value = nil }