Bladeren bron

Add back accidentally missing MaxDelta xx > yy% of BG zz

Daniel Snällfot 1 jaar geleden
bovenliggende
commit
e05fb2a7c3
1 gewijzigde bestanden met toevoegingen van 101 en 65 verwijderingen
  1. 101 65
      FreeAPS/Sources/Services/Network/Nightscout/NightscoutManager.swift

+ 101 - 65
FreeAPS/Sources/Services/Network/Nightscout/NightscoutManager.swift

@@ -1131,7 +1131,7 @@ extension BaseNightscoutManager {
 
      - Glucose tags handled: `ISF:`, `Target:`, `minPredBG`, `minGuardBG`, `IOBpredBG`, `COBpredBG`, `UAMpredBG`, `Dev:`, `maxDelta`, `BG`.
      */
-        func parseReasonGlucoseValuesToMmolL(_ reason: String) -> String {
+            func parseReasonGlucoseValuesToMmolL(_ reason: String) -> String {
         let patterns = [
             "ISF:\\s*-?\\d+\\.?\\d*→-?\\d+\\.?\\d*",
             "Dev:\\s*-?\\d+\\.?\\d*",
@@ -1139,13 +1139,16 @@ extension BaseNightscoutManager {
             "Target:\\s*-?\\d+\\.?\\d*",
             "(?:minPredBG|minGuardBG|IOBpredBG|COBpredBG|UAMpredBG)\\s+-?\\d+\\.?\\d*(?:<-?\\d+\\.?\\d*)?",
             "minGuardBG\\s+-?\\d+\\.?\\d*<-?\\d+\\.?\\d*",
-            "Eventual BG\\s+-?\\d+\\.?\\d*\\s*>=\\s*-?\\d+\\.?\\d*"
+            "Eventual BG\\s+-?\\d+\\.?\\d*\\s*>=\\s*-?\\d+\\.?\\d*",
+            "\\S+\\s+\\d+\\s*>\\s*\\d+%\\s+of\\s+BG\\s+\\d+"
         ]
         let pattern = patterns.joined(separator: "|")
         let regex = try! NSRegularExpression(pattern: pattern)
 
         func convertToMmolL(_ value: String) -> String {
-            if let glucoseValue = Double(value.replacingOccurrences(of: "[^\\d.-]", with: "", options: .regularExpression)) {
+            if let glucoseValue = Double(
+                value.replacingOccurrences(of: "[^\\d.-]", with: "", options: .regularExpression)
+            ) {
                 let mmolValue = Decimal(glucoseValue).asMmolL
                 return mmolValue.description
             }
@@ -1153,74 +1156,107 @@ extension BaseNightscoutManager {
         }
 
         let matches = regex.matches(in: reason, range: NSRange(reason.startIndex..., in: reason))
+
         var updatedReason = reason
-        for (index, match) in matches.reversed().enumerated() {
-            if let range = Range(match.range, in: reason) {
-                let glucoseValueString = String(reason[range])
-
-                if glucoseValueString.contains("→") {
-                    // Handle ISF case
-                    let values = glucoseValueString.components(separatedBy: "→")
-                    let firstNumber = values[0].components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
-                    let secondNumber = values[1].trimmingCharacters(in: .whitespaces)
-                    let firstValue = convertToMmolL(firstNumber)
-                    let secondValue = convertToMmolL(secondNumber)
-                    let formattedString = "ISF: \(firstValue)→\(secondValue)"
-                    updatedReason.replaceSubrange(range, with: formattedString)
 
-                } else if glucoseValueString.contains("<") {
-                    // Handle minGuardBG x<target case
-                    let components = glucoseValueString
-                        .split(whereSeparator: { "<".contains($0) || CharacterSet.whitespaces.contains($0.unicodeScalars.first!)
-                        })
-                        .filter { !$0.isEmpty }
-                    if components.count >= 3 {
-                        let firstValue = convertToMmolL(String(components[1]))
-                        let secondValue = convertToMmolL(String(components[2]))
-                        let formattedString = "\(components[0]) \(firstValue)<\(secondValue)"
-                        updatedReason.replaceSubrange(range, with: formattedString)
-                    }
-                } else if glucoseValueString.contains(">=") {
-                    // Handle Eventual BG x >= y case
-                    let components = glucoseValueString
-                        .split(whereSeparator: { " >= ".contains($0) ||
-                                CharacterSet.whitespaces.contains($0.unicodeScalars.first!) })
-                        .filter { !$0.isEmpty }
-                    if components.count == 4 {
-                        let firstValue = convertToMmolL(String(components[2]))
-                        let secondValue = convertToMmolL(String(components[3]))
-                        let formattedString = "\(components[0]) \(components[1]) \(firstValue) >= \(secondValue)"
-                        updatedReason.replaceSubrange(range, with: formattedString)
-                    }
-                } else if glucoseValueString.starts(with: "Dev:") {
-                    // Handle Dev case
-                    let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
-                    let formattedValue = convertToMmolL(value)
-                    let formattedString = "Dev: \(formattedValue)"
+        for match in matches.reversed() {
+            guard let range = Range(match.range, in: reason) else { continue }
+            let glucoseValueString = String(reason[range])
+
+            if glucoseValueString.contains("→") {
+                // -- Handle ISF: X→Y
+                let values = glucoseValueString.components(separatedBy: "→")
+                let firstNumber = values[0].components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
+                let secondNumber = values[1].trimmingCharacters(in: .whitespaces)
+                let firstValue = convertToMmolL(firstNumber)
+                let secondValue = convertToMmolL(secondNumber)
+                let formattedString = "ISF: \(firstValue)→\(secondValue)"
+                updatedReason.replaceSubrange(range, with: formattedString)
+
+            } else if glucoseValueString.contains("<") {
+                // -- Handle minGuardBG (or minPredBG, etc.) x < y
+                let components = glucoseValueString
+                    .split(whereSeparator: { "<".contains($0) ||
+                            CharacterSet.whitespaces.contains($0.unicodeScalars.first!) })
+                    .filter { !$0.isEmpty }
+
+                if components.count >= 3 {
+                    let firstValue = convertToMmolL(String(components[1]))
+                    let secondValue = convertToMmolL(String(components[2]))
+                    let formattedString = "\(components[0]) \(firstValue)<\(secondValue)"
                     updatedReason.replaceSubrange(range, with: formattedString)
-                } else if glucoseValueString.starts(with: "BGI:") {
-                    // Handle BGI case
-                    let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
-                    let formattedValue = convertToMmolL(value)
-                    let formattedString = "BGI: \(formattedValue)"
+                }
+
+            } else if glucoseValueString.contains(">=") {
+                // -- Handle "Eventual BG X >= Y"
+                let components = glucoseValueString
+                    .split(whereSeparator: { " >= ".contains($0) ||
+                            CharacterSet.whitespaces.contains($0.unicodeScalars.first!) })
+                    .filter { !$0.isEmpty }
+
+                if components.count == 4 {
+                    let firstValue = convertToMmolL(String(components[2]))
+                    let secondValue = convertToMmolL(String(components[3]))
+                    let formattedString = "\(components[0]) \(components[1]) \(firstValue) >= \(secondValue)"
                     updatedReason.replaceSubrange(range, with: formattedString)
-                } else if glucoseValueString.starts(with: "Target:") {
-                    // Handle Target case
-                    let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
+                }
+
+            } else if glucoseValueString.starts(with: "Dev:") {
+                // -- Handle Dev
+                let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
+                let formattedValue = convertToMmolL(value)
+                let formattedString = "Dev: \(formattedValue)"
+                updatedReason.replaceSubrange(range, with: formattedString)
+
+            } else if glucoseValueString.starts(with: "BGI:") {
+                // -- Handle BGI
+                let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
+                let formattedValue = convertToMmolL(value)
+                let formattedString = "BGI: \(formattedValue)"
+                updatedReason.replaceSubrange(range, with: formattedString)
+
+            } else if glucoseValueString.starts(with: "Target:") {
+                // -- Handle Target
+                let value = glucoseValueString.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces)
+                let formattedValue = convertToMmolL(value)
+                let formattedString = "Target: \(formattedValue)"
+                updatedReason.replaceSubrange(range, with: formattedString)
+
+            } else if glucoseValueString.contains(">"), glucoseValueString.contains("BG") {
+                // -- Handle "maxDelta 37 > 20% of BG 95" style
+                // Run a local regex that picks out the two BG values
+                let localPattern = "(\\d+) > (\\d+)% of BG (\\d+)"
+                let localRegex = try! NSRegularExpression(pattern: localPattern)
+                let localMatches = localRegex.matches(
+                    in: glucoseValueString,
+                    range: NSRange(glucoseValueString.startIndex..., in: glucoseValueString)
+                )
+                if let localMatch = localMatches.first, localMatch.numberOfRanges == 4 {
+                    let range1 = Range(localMatch.range(at: 1), in: glucoseValueString)!
+                    let range2 = Range(localMatch.range(at: 2), in: glucoseValueString)!
+                    let range3 = Range(localMatch.range(at: 3), in: glucoseValueString)!
+
+                    let firstValue = convertToMmolL(String(glucoseValueString[range1]))
+                    let thirdValue = convertToMmolL(String(glucoseValueString[range3]))
+
+                    // e.g. "37 > 20% of BG 95" → "2.1 > 20% of BG 5.3"
+                    let oldSnippet =
+                        "\(glucoseValueString[range1]) > \(glucoseValueString[range2])% of BG \(glucoseValueString[range3])"
+                    let newSnippet = "\(firstValue) > \(glucoseValueString[range2])% of BG \(thirdValue)"
+
+                    let replaced = glucoseValueString.replacingOccurrences(of: oldSnippet, with: newSnippet)
+                    updatedReason.replaceSubrange(range, with: replaced)
+                }
+                
+            } else {
+                // -- Handle everything else, e.g. "minPredBG 39", "COB 29", etc.
+                let parts = glucoseValueString.components(separatedBy: .whitespaces)
+                if parts.count >= 2 {
+                    let metric = parts[0]
+                    let value = parts[1]
                     let formattedValue = convertToMmolL(value)
-                    let formattedString = "Target: \(formattedValue)"
+                    let formattedString = "\(metric): \(formattedValue)"
                     updatedReason.replaceSubrange(range, with: formattedString)
-
-                } else {
-                    // Handle standard BG metrics
-                    let parts = glucoseValueString.components(separatedBy: .whitespaces)
-                    if parts.count >= 2 {
-                        let metric = parts[0]
-                        let value = parts[1]
-                        let formattedValue = convertToMmolL(value)
-                        let formattedString = "\(metric): \(formattedValue)"
-                        updatedReason.replaceSubrange(range, with: formattedString)
-                    }
                 }
             }
         }