diff --git a/nightguard WatchKit Extension/ChartPainter.swift b/nightguard WatchKit Extension/ChartPainter.swift index 912de62e..edfe4152 100644 --- a/nightguard WatchKit Extension/ChartPainter.swift +++ b/nightguard WatchKit Extension/ChartPainter.swift @@ -251,18 +251,18 @@ class ChartPainter { // paint the maximum BGValue Label only if it has enought space and doesn't intersect with // the upper bound BGValue if maxBgValueAsFloat > upperBoundNiceValue + 25 { - let maxBgValueString = UnitsConverter.toDisplayUnits(maxBgValueAsFloat.cleanValue) + let maxBgValueString = UnitsConverter.mgdlToDisplayUnits(maxBgValueAsFloat.cleanValue) maxBgValueString.draw( with: CGRect(x: CGFloat(x), y: CGFloat.init(calcYValue(maxBgValueAsFloat)) + 3, width: 40, height: 14), options: .usesLineFragmentOrigin, attributes: attrs, context: nil) } - let upperBoundString = UnitsConverter.toDisplayUnits(upperBoundNiceValue.cleanValue) + let upperBoundString = UnitsConverter.mgdlToDisplayUnits(upperBoundNiceValue.cleanValue) upperBoundString.draw( with: CGRect(x: CGFloat(x), y: CGFloat.init(calcYValue(upperBoundNiceValue)), width: 40, height: 14), options: .usesLineFragmentOrigin, attributes: attrs, context: nil) - let lowerBoundString = UnitsConverter.toDisplayUnits(lowerBoundNiceValue.cleanValue) + let lowerBoundString = UnitsConverter.mgdlToDisplayUnits(lowerBoundNiceValue.cleanValue) lowerBoundString.draw( with: CGRect(x: CGFloat(x), y: CGFloat.init(calcYValue(lowerBoundNiceValue))-15, width: 40, height: 14), options: .usesLineFragmentOrigin, attributes: attrs, context: nil) diff --git a/nightguard WatchKit Extension/ComplicationController.swift b/nightguard WatchKit Extension/ComplicationController.swift index e38c19d7..5abeb579 100644 --- a/nightguard WatchKit Extension/ComplicationController.swift +++ b/nightguard WatchKit Extension/ComplicationController.swift @@ -44,13 +44,13 @@ class ComplicationController: NSObject, CLKComplicationDataSource { if useRelativeTimeWhenPossible { modTemplate.line1TextProvider = CLKSimpleTextProvider(text: getSgvAndArrow(currentNightscoutData, " ")) modTemplate.line1TextProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.line2TextProvider = getRelativeDateTextProvider(for: currentNightscoutData.time) } else { modTemplate.line1TextProvider = CLKSimpleTextProvider(text: "\(currentNightscoutData.hourAndMinutes)") modTemplate.line1TextProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) - modTemplate.line2TextProvider = CLKSimpleTextProvider(text: "\(currentNightscoutData.sgv)\(UnitsConverter.toDisplayDeltaUnits(currentNightscoutData.bgdeltaString))\(currentNightscoutData.bgdeltaArrow)") + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) + modTemplate.line2TextProvider = CLKSimpleTextProvider(text: "\(UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv))\(UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdeltaString))\(currentNightscoutData.bgdeltaArrow)") } template = modTemplate case .modularLarge: @@ -59,7 +59,7 @@ class ComplicationController: NSObject, CLKComplicationDataSource { modTemplate.row1Column1TextProvider = CLKSimpleTextProvider(text: getOneLine(currentNightscoutData)) modTemplate.row1Column1TextProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.row1Column2TextProvider = getRelativeDateTextProvider(for: currentNightscoutData.time) modTemplate.row2Column1TextProvider = CLKSimpleTextProvider(text: "") modTemplate.row2Column2TextProvider = CLKSimpleTextProvider(text: "") @@ -95,20 +95,21 @@ class ComplicationController: NSObject, CLKComplicationDataSource { let modTemplate = CLKComplicationTemplateUtilitarianSmallFlat() modTemplate.textProvider = CLKSimpleTextProvider(text: self.getOneBigLine(currentNightscoutData)) modTemplate.textProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) template = modTemplate case .utilitarianLarge: let modTemplate = CLKComplicationTemplateUtilitarianLargeFlat() modTemplate.imageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!) modTemplate.textProvider = CLKSimpleTextProvider(text: self.getOneBigLine(currentNightscoutData)) modTemplate.textProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) template = modTemplate case .circularSmall: let modTemplate = CLKComplicationTemplateCircularSmallRingText() - modTemplate.textProvider = CLKSimpleTextProvider(text: UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + modTemplate.textProvider = CLKSimpleTextProvider(text: + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.textProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.fillFraction = self.getAgeOfDataInMinutes(currentNightscoutData.time) / 60 modTemplate.ringStyle = CLKComplicationRingStyle.closed @@ -118,7 +119,7 @@ class ComplicationController: NSObject, CLKComplicationDataSource { let modTemplate = CLKComplicationTemplateGraphicCornerStackText() modTemplate.outerTextProvider = CLKSimpleTextProvider(text: self.getOneShortLine(currentNightscoutData)) modTemplate.outerTextProvider.tintColor = UIColorChanger.getBgColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.innerTextProvider = CLKSimpleTextProvider(text: self.getLastReadingTime(currentNightscoutData)) template = modTemplate } else { @@ -127,8 +128,9 @@ class ComplicationController: NSObject, CLKComplicationDataSource { case .graphicCircular: if #available(watchOSApplicationExtension 5.0, *) { let modTemplate = CLKComplicationTemplateGraphicCircularClosedGaugeText() - modTemplate.centerTextProvider = CLKSimpleTextProvider(text: "\(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv))") - modTemplate.centerTextProvider.tintColor = UIColorChanger.getBgColor(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + modTemplate.centerTextProvider = CLKSimpleTextProvider(text: "\(UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv))") + modTemplate.centerTextProvider.tintColor = UIColorChanger.getBgColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) modTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: UIColor.black, fillFraction: 0.0) template = modTemplate } else { @@ -138,7 +140,8 @@ class ComplicationController: NSObject, CLKComplicationDataSource { if #available(watchOSApplicationExtension 5.0, *) { let modTemplate = CLKComplicationTemplateGraphicBezelCircularText() modTemplate.textProvider = CLKSimpleTextProvider(text: self.getOneBigLine(currentNightscoutData)) - modTemplate.textProvider?.tintColor = UIColorChanger.getBgColor(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + modTemplate.textProvider?.tintColor = UIColorChanger.getBgColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) let modImageTemplate = CLKComplicationTemplateGraphicCircularImage() modImageTemplate.imageProvider = CLKFullColorImageProvider(fullColorImage: UIImage(named: "Complication/Graphic Circular")!) modTemplate.circularTemplate = modImageTemplate @@ -173,7 +176,7 @@ class ComplicationController: NSObject, CLKComplicationDataSource { // Display 11:24 113+2 func getOneBigLine(_ data : NightscoutData) -> String { - return "\(data.hourAndMinutes) \(UnitsConverter.toDisplayUnits(data.sgv))\(UnitsConverter.toDisplayDeltaUnits(data.bgdeltaString))\(data.bgdeltaArrow)" + return "\(data.hourAndMinutes) \(UnitsConverter.mgdlToDisplayUnits(data.sgv))\(UnitsConverter.mgdlToDisplayUnits(data.bgdeltaString))\(data.bgdeltaArrow)" } // Display 11:24 @@ -183,12 +186,12 @@ class ComplicationController: NSObject, CLKComplicationDataSource { // Displays 113 ↗ +2 func getOneLine(_ data : NightscoutData) -> String { - return "\(getSgvAndArrow(data, " "))\t\(UnitsConverter.toDisplayDeltaUnits(data.bgdeltaString))" + return "\(getSgvAndArrow(data, " "))\t\(UnitsConverter.mgdlToDisplayUnits(data.bgdeltaString))" } // Displays 113↗+2 func getOneShortLine(_ data : NightscoutData) -> String { - return "\(getSgvAndArrow(data, ""))\(UnitsConverter.toDisplayDeltaUnits(data.bgdeltaString))" + return "\(getSgvAndArrow(data, ""))\(UnitsConverter.mgdlToDisplayUnits(data.bgdeltaString))" } func getSgvAndArrow(_ data: NightscoutData, _ separator: String) -> String { @@ -201,7 +204,7 @@ class ComplicationController: NSObject, CLKComplicationDataSource { bgdeltaArrow = "⇊" } - return [UnitsConverter.toDisplayUnits(data.sgv), bgdeltaArrow].joined(separator: separator) + return [UnitsConverter.mgdlToDisplayUnits(data.sgv), bgdeltaArrow].joined(separator: separator) } // If the age is older than 59 minutes => return 60 in that case diff --git a/nightguard WatchKit Extension/InterfaceController.swift b/nightguard WatchKit Extension/InterfaceController.swift index 55bfd261..0a3e7966 100644 --- a/nightguard WatchKit Extension/InterfaceController.swift +++ b/nightguard WatchKit Extension/InterfaceController.swift @@ -362,13 +362,16 @@ class InterfaceController: WKInterfaceController, WKCrownDelegate { fileprivate func paintCurrentBgData(currentNightscoutData : NightscoutData) { - self.bgLabel.setText(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) - self.bgLabel.setTextColor(UIColorChanger.getBgColor(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv))) + self.bgLabel.setText( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) + self.bgLabel.setTextColor(UIColorChanger.getBgColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv))) - self.deltaLabel.setText(UnitsConverter.toDisplayDeltaUnits(currentNightscoutData.bgdeltaString)) + self.deltaLabel.setText( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdeltaString)) self.deltaArrowLabel.setText(currentNightscoutData.bgdeltaArrow) self.deltaLabel.setTextColor(UIColorChanger.getDeltaLabelColor( - UnitsConverter.toDisplayUnits(currentNightscoutData.bgdelta))) + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdelta))) self.timeLabel.setText(currentNightscoutData.timeString) self.timeLabel.setTextColor(UIColorChanger.getTimeLabelColor(currentNightscoutData.time)) diff --git a/nightguard/AlarmViewController.swift b/nightguard/AlarmViewController.swift index f699e3e8..a6a33fbf 100644 --- a/nightguard/AlarmViewController.swift +++ b/nightguard/AlarmViewController.swift @@ -38,7 +38,10 @@ class AlarmViewController: CustomFormViewController { override func constructForm() { - aboveSliderRow = SliderRow.glucoseLevelSlider(initialValue: AlarmRule.alertIfAboveValue.value, minimumValue: MIN_ALERT_ABOVE_VALUE, maximumValue: MAX_ALERT_ABOVE_VALUE) + aboveSliderRow = SliderRow.glucoseLevelSlider( + initialValue: UnitsConverter.mgdlToDisplayUnits(AlarmRule.alertIfAboveValue.value), + minimumValue: UnitsConverter.mgdlToDisplayUnits(MIN_ALERT_ABOVE_VALUE), + maximumValue: UnitsConverter.mgdlToDisplayUnits(MAX_ALERT_ABOVE_VALUE)) aboveSliderRow.cell.slider.addTarget(self, action: #selector(onSliderValueChanged(slider:event:)), for: .valueChanged) belowSliderRow = SliderRow.glucoseLevelSlider(initialValue: AlarmRule.alertIfBelowValue.value, minimumValue: MIN_ALERT_BELOW_VALUE, maximumValue: MAX_ALERT_BELOW_VALUE) @@ -111,7 +114,7 @@ class AlarmViewController: CustomFormViewController { if AlarmRule.isEdgeDetectionAlarmEnabled.value { let deltaInMgdl = AlarmRule.deltaAmount.value - let delta = UnitsConverter.toDisplayUnits("\(deltaInMgdl)") + let delta = UnitsConverter.mgdlToDisplayUnits("\(deltaInMgdl)") let units = UserDefaultsRepository.units.value.description let consecutiveValue = AlarmRule.numberOfConsecutiveValues.value @@ -135,7 +138,7 @@ class AlarmViewController: CustomFormViewController { row.detailTextProvider = { let urgentHighInMgdl = AlarmRule.persistentHighUpperBound.value - let urgentHigh = UnitsConverter.toDisplayUnits("\(urgentHighInMgdl)") + let urgentHigh = UnitsConverter.mgdlToDisplayUnits("\(urgentHighInMgdl)") let units = UserDefaultsRepository.units.value.description let urgentHighWithUnits = "\(urgentHigh) \(units)" @@ -259,9 +262,9 @@ class AlarmViewController: CustomFormViewController { } private func updateSliderRowsFromUserDefaultsValues() { - aboveSliderRow.value = Float(UnitsConverter.toDisplayUnits("\(AlarmRule.alertIfAboveValue.value)"))! + aboveSliderRow.value = Float(UnitsConverter.mgdlToDisplayUnits("\(AlarmRule.alertIfAboveValue.value)")) aboveSliderRow.updateCell() - belowSliderRow.value = Float(UnitsConverter.toDisplayUnits("\(AlarmRule.alertIfBelowValue.value)"))! + belowSliderRow.value = Float(UnitsConverter.mgdlToDisplayUnits("\(AlarmRule.alertIfBelowValue.value)")) belowSliderRow.updateCell() } } diff --git a/nightguard/CustomFormViewController.swift b/nightguard/CustomFormViewController.swift index 09052ac5..42aba2a4 100644 --- a/nightguard/CustomFormViewController.swift +++ b/nightguard/CustomFormViewController.swift @@ -250,11 +250,11 @@ extension SliderRow { class func glucoseLevelSlider(initialValue: Float, minimumValue: Float, maximumValue: Float, snapIncrementForMgDl: Float = 10.0) -> SliderRow { return SliderRow() { row in - row.value = Float(UnitsConverter.toDisplayUnits("\(initialValue)"))! + row.value = initialValue }.cellSetup { cell, row in - let minimumValue = Float(UnitsConverter.toDisplayUnits("\(minimumValue)"))! - let maximumValue = Float(UnitsConverter.toDisplayUnits("\(maximumValue)"))! + let minimumValue = Float(UnitsConverter.mgdlToDisplayUnits("\(minimumValue)"))! + let maximumValue = Float(UnitsConverter.mgdlToDisplayUnits("\(maximumValue)"))! let snapIncrement = (UserDefaultsRepository.units.value == .mgdl) ? snapIncrementForMgDl : 0.1 let steps = (maximumValue - minimumValue) / snapIncrement diff --git a/nightguard/MainViewController.swift b/nightguard/MainViewController.swift index 1bc1e354..b99e849e 100644 --- a/nightguard/MainViewController.swift +++ b/nightguard/MainViewController.swift @@ -461,14 +461,17 @@ class MainViewController: UIViewController, SlideToSnoozeDelegate { if currentNightscoutData.sgv == "---" { self.bgLabel.text = "---" } else { - self.bgLabel.text = UnitsConverter.toDisplayUnits(currentNightscoutData.sgv) + self.bgLabel.text = UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv) } - self.bgLabel.textColor = UIColorChanger.getBgColor(UnitsConverter.toDisplayUnits(currentNightscoutData.sgv)) + self.bgLabel.textColor = UIColorChanger.getBgColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.sgv)) - self.deltaLabel.text = UnitsConverter.toDisplayDeltaUnits(currentNightscoutData.bgdeltaString) + self.deltaLabel.text = UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdeltaString) self.deltaArrowsLabel.text = currentNightscoutData.bgdeltaArrow - self.deltaLabel.textColor = UIColorChanger.getDeltaLabelColor(currentNightscoutData.bgdelta) - self.deltaArrowsLabel.textColor = UIColorChanger.getDeltaLabelColor(currentNightscoutData.bgdelta) + self.deltaLabel.textColor = UIColorChanger.getDeltaLabelColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdelta)) + self.deltaArrowsLabel.textColor = UIColorChanger.getDeltaLabelColor( + UnitsConverter.mgdlToDisplayUnits(currentNightscoutData.bgdelta)) self.lastUpdateLabel.text = currentNightscoutData.timeString self.lastUpdateLabel.textColor = UIColorChanger.getTimeLabelColor(currentNightscoutData.time) @@ -542,7 +545,7 @@ class MainViewController: UIViewController, SlideToSnoozeDelegate { let temporaryTargetData = NightscoutCacheService.singleton.getTemporaryTargetData() if temporaryTargetData.activeUntilDate.remainingMinutes() > 0 { - self.temporaryTargetLabel.text = "TT \(UnitsConverter.toDisplayUnits(temporaryTargetData.targetTop)) \(temporaryTargetData.activeUntilDate.remainingMinutes())m" + self.temporaryTargetLabel.text = "TT \(UnitsConverter.mgdlToDisplayUnits("\(temporaryTargetData.targetTop)")) \(temporaryTargetData.activeUntilDate.remainingMinutes())m" } else { self.temporaryTargetLabel.text = "TT --" } diff --git a/nightguard/NightscoutService.swift b/nightguard/NightscoutService.swift index fd8d53be..6b59a8ab 100644 --- a/nightguard/NightscoutService.swift +++ b/nightguard/NightscoutService.swift @@ -368,7 +368,11 @@ class NightscoutService { } // Get the current data from REST-Call - let url = UserDefaultsRepository.getUrlWithPathAndQueryParameters(path: "pebble", queryParams: ["": ""]) + // Force mgdl here, since all values are kept internall in mgdl. + // Only for the UI, they are transformed to mmol. This enables us to let the user manually + // switch to the wished units. + // All other endpoints deliver in mgdl, too. So this makes sence to enforce it here, too: + let url = UserDefaultsRepository.getUrlWithPathAndQueryParameters(path: "pebble", queryParams: ["units": "mgdl"]) guard url != nil else { resultHandler(.error(createEmptyOrInvalidUriError())) return nil diff --git a/nightguard/PersistentHighViewController.swift b/nightguard/PersistentHighViewController.swift index 60c008a4..6abbf39e 100644 --- a/nightguard/PersistentHighViewController.swift +++ b/nightguard/PersistentHighViewController.swift @@ -33,7 +33,10 @@ class PersistentHighViewController: CustomFormViewController { } } - urgentHighSliderRow = SliderRow.glucoseLevelSlider(initialValue: AlarmRule.persistentHighUpperBound.value, minimumValue: AlarmRule.alertIfAboveValue.value, maximumValue: 300) + urgentHighSliderRow = SliderRow.glucoseLevelSlider( + initialValue: UnitsConverter.mgdlToDisplayUnits(AlarmRule.persistentHighUpperBound.value), + minimumValue: UnitsConverter.mgdlToDisplayUnits(AlarmRule.alertIfAboveValue.value), + maximumValue: UnitsConverter.mgdlToDisplayUnits(300)) urgentHighSliderRow.cell.slider.addTarget(self, action: #selector(onSliderValueChanged(slider:event:)), for: .valueChanged) let urgentHighSection = Section(header: NSLocalizedString("Urgent High", comment: "Label for Urgent High"), footer: NSLocalizedString("Alerts anytime when the blood glucose raises above this value.", comment: "Footer for Urgent High")) @@ -65,7 +68,7 @@ class PersistentHighViewController: CustomFormViewController { guard let value = urgentHighSliderRow.value else { return } let mgdlValue = UnitsConverter.toMgdl(value) - print("Changed (persistent) urgent high slider to \(mgdlValue) \(UserDefaultsRepository.units.value.description)") + print("Changed (persistent) urgent high slider to \(value) \(UserDefaultsRepository.units.value.description)") AlarmRule.persistentHighUpperBound.value = mgdlValue } diff --git a/nightguard/UnitsConverter.swift b/nightguard/UnitsConverter.swift index 5f7bdd8d..0e0edb9f 100644 --- a/nightguard/UnitsConverter.swift +++ b/nightguard/UnitsConverter.swift @@ -16,6 +16,26 @@ class UnitsConverter { // Converts the internally mg/dL to mmol if thats the defined // Unit to be used. + static func mgdlToDisplayUnits(_ value : String) -> String { + + if value == "---" { + return value + } + + let units = UserDefaultsRepository.units.value + if units == Units.mgdl { + // nothing to do here - just remove decimals + if value.contains(".") { + return String(value.prefix(upTo: value.firstIndex(of: ".") ?? value.endIndex)) + } + return value + } + + return toMmol(value) + } + + // Converts uncertain value to the wished unit + // Unit to be used. static func toDisplayUnits(_ value : String) -> String { if value == "---" { @@ -46,6 +66,17 @@ class UnitsConverter { // Converts the internally mg/dL to mmol if thats the defined // Unit to be used. + static func mgdlToDisplayUnits(_ value : Float) -> Float { + + let units = UserDefaultsRepository.units.value + if units == Units.mgdl { + return removeDecimals(value) + } + + // convert mg/dL to mmol/l + return value * 0.0555 + } + static func toDisplayUnits(_ value : Float) -> Float { let units = UserDefaultsRepository.units.value @@ -111,9 +142,9 @@ class UnitsConverter { static func toMmol(_ uncertainValue : String) -> String { - // determine whether mmol is already contained + // determine whether mmol is already contained var doubleValue : Double = Double(uncertainValue)! - if (doubleValue < 40) { + if uncertainValue.contains(".") { // the value seems to be already mmol -> nothing to do return uncertainValue.cleanFloatValue } @@ -159,13 +190,7 @@ class UnitsConverter { static func toMgdl(_ uncertainValue : String) -> String { var floatValue : Float = Float(uncertainValue)! - if (floatValue > 40) { - // the value seems to be already mgdl -> nothing to do - return String(floatValue.cleanValue) - } - - // looks like mmol is contained - // convert mmol to mg/dl + floatValue = floatValue * (1 / 0.0555) return String(floatValue.cleanValue) }