فهرست منبع

Refactor mmol/L handling; introduce units and parsing WIP

Deniz Cengiz 1 سال پیش
والد
کامیت
f73d00da5c

+ 20 - 9
FreeAPS/Sources/Models/DecimalPickerSettings.swift

@@ -82,9 +82,9 @@ struct DecimalPickerSettings {
         type: PickerSetting.PickerSettingType.factor
     )
     var remainingCarbsCap = PickerSetting(value: 90, step: 5, min: 0, max: 200, type: PickerSetting.PickerSettingType.gramms)
-    var maxSMBBasalMinutes = PickerSetting(value: 30, step: 1, min: 0, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var maxUAMSMBBasalMinutes = PickerSetting(value: 30, step: 1, min: 0, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var smbInterval = PickerSetting(value: 3, step: 0.1, min: 0.5, max: 10, type: PickerSetting.PickerSettingType.factor)
+    var maxSMBBasalMinutes = PickerSetting(value: 30, step: 1, min: 0, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var maxUAMSMBBasalMinutes = PickerSetting(value: 30, step: 1, min: 0, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var smbInterval = PickerSetting(value: 3, step: 0.1, min: 0.5, max: 10, type: PickerSetting.PickerSettingType.minute)
     var bolusIncrement = PickerSetting(
         value: 0.1,
         step: 0.1,
@@ -101,7 +101,13 @@ struct DecimalPickerSettings {
         max: 2,
         type: PickerSetting.PickerSettingType.factor
     )
-    var maxDeltaBGthreshold = PickerSetting(value: 0.2, step: 0.1, min: 0.1, max: 2, type: PickerSetting.PickerSettingType.factor)
+    var maxDeltaBGthreshold = PickerSetting(
+        value: 0.2,
+        step: 0.1,
+        min: 0.1,
+        max: 2,
+        type: PickerSetting.PickerSettingType.glucose
+    )
     var adjustmentFactor = PickerSetting(value: 0.8, step: 0.1, min: 0.5, max: 1.5, type: PickerSetting.PickerSettingType.factor)
     var adjustmentFactorSigmoid = PickerSetting(
         value: 0.5,
@@ -119,11 +125,14 @@ struct DecimalPickerSettings {
         type: PickerSetting.PickerSettingType.glucose
     )
     var threshold_setting = PickerSetting(value: 65, step: 1, min: 50, max: 100, type: PickerSetting.PickerSettingType.glucose)
-    var updateInterval = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var delay = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var minuteInterval = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var timeCap = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.factor)
-    var hours = PickerSetting(value: 6, step: 1, min: 2, max: 24, type: PickerSetting.PickerSettingType.factor)
+    var updateInterval = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var delay = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var minuteInterval = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var timeCap = PickerSetting(value: 20, step: 1, min: 1, max: 60, type: PickerSetting.PickerSettingType.minute)
+    var hours = PickerSetting(value: 6, step: 1, min: 2, max: 24, type: PickerSetting.PickerSettingType.hour)
+    var dia = PickerSetting(value: 6, step: 0.5, min: 4, max: 10, type: PickerSetting.PickerSettingType.hour)
+    var maxBolus = PickerSetting(value: 10, step: 1, min: 1, max: 30, type: PickerSetting.PickerSettingType.insulinUnit)
+    var maxBasal = PickerSetting(value: 10, step: 1, min: 1, max: 30, type: PickerSetting.PickerSettingType.insulinUnit)
 }
 
 struct PickerSetting {
@@ -138,5 +147,7 @@ struct PickerSetting {
         case factor
         case gramms
         case insulinUnit
+        case minute
+        case hour
     }
 }

+ 3 - 3
FreeAPS/Sources/Modules/DynamicSettings/View/DynamicSettingsRootView.swift

@@ -194,14 +194,14 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0
-                                hintLabel = "Threshold Setting"
+                                hintLabel = "Minimum Safety Threshold"
                             }
                         ),
                         units: state.units,
                         type: .decimal("threshold_setting"),
-                        label: "Threshold Setting",
+                        label: "Minimum Safety Threshold",
                         miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
-                        verboseHint: "BG threshold"
+                        verboseHint: "Minimum Safety Threshold… bla bla bla"
                     )
                 }
             }

+ 1 - 6
FreeAPS/Sources/Modules/ISFEditor/ISFEditorStateModel.swift

@@ -16,12 +16,7 @@ extension ISFEditor {
         let timeValues = stride(from: 0.0, to: 1.days.timeInterval, by: 30.minutes.timeInterval).map { $0 }
 
         var rateValues: [Decimal] {
-            switch units {
-            case .mgdL:
-                return stride(from: 9, to: 540.01, by: 1.0).map { Decimal($0) }
-            case .mmolL:
-                return stride(from: 1.0, to: 301.0, by: 1.0).map { ($0.decimal ?? .zero) / 10 }
-            }
+            stride(from: 9, to: 540.01, by: 1.0).map { Decimal($0) }
         }
 
         var canAdd: Bool {

+ 12 - 2
FreeAPS/Sources/Modules/ISFEditor/View/ISFEditorRootView.swift

@@ -136,7 +136,10 @@ extension ISFEditor {
                             Text(
                                 (
                                     self.rateFormatter
-                                        .string(from: state.rateValues[i] as NSNumber) ?? ""
+                                        .string(
+                                            from: state.units == .mgdL ? state.rateValues[i] as NSNumber : state.rateValues[i]
+                                                .asMmolL as NSNumber
+                                        ) ?? ""
                                 ) + " \(state.units.rawValue)/U"
                             ).tag(i)
                         }
@@ -166,11 +169,18 @@ extension ISFEditor {
         private var list: some View {
             List {
                 ForEach(state.items.indexed(), id: \.1.id) { index, item in
+                    let displayValue = rateFormatter
+                        .string(
+                            from: state.units == .mgdL ? state.rateValues[item.rateIndex] as NSNumber : state
+                                .rateValues[item.rateIndex].asMmolL as NSNumber
+                        )
+
                     NavigationLink(destination: pickers(for: index)) {
                         HStack {
                             Text("Rate").foregroundColor(.secondary)
+
                             Text(
-                                "\(rateFormatter.string(from: state.rateValues[item.rateIndex] as NSNumber) ?? "0") \(state.units.rawValue)/U"
+                                "\(displayValue ?? "0") \(state.units.rawValue)/U"
                             )
                             Spacer()
                             Text("starts at").foregroundColor(.secondary)

+ 34 - 39
FreeAPS/Sources/Modules/PumpSettingsEditor/View/PumpSettingsEditorRootView.swift

@@ -39,46 +39,41 @@ extension PumpSettingsEditor {
 
         var body: some View {
             Form {
-                Section(
-                    header: Text("Insulin Pump Configuration"),
-                    content: {
-                        VStack {
-                            HStack {
-                                Text("Max Basal")
-                                Spacer()
-                                TextFieldWithToolBar(text: $state.maxBasal, placeholder: "0", numberFormatter: formatter)
-                            }.padding(.top)
-                            HStack {
-                                Text("Max Bolus")
-                                Spacer()
-                                TextFieldWithToolBar(text: $state.maxBolus, placeholder: "0", numberFormatter: formatter)
-                            }
-
-                            HStack(alignment: .top) {
-                                Text(
-                                    "Sets delivery limits for basal and bolus insulin on pump."
-                                )
-                                .lineLimit(nil)
-                                .font(.footnote)
-                                .foregroundColor(.secondary)
+                SettingInputSection(
+                    decimalValue: $state.maxBolus,
+                    booleanValue: $booleanPlaceholder,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Max Bolus"
+                        }
+                    ),
+                    units: state.units,
+                    type: .decimal("maxBolus"),
+                    label: "Max Bolus",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Max Bolus… bla bla bla"
+                )
 
-                                Spacer()
-                                Button(
-                                    action: {
-                                        hintLabel = "Insulin Delivery limits"
-                                        selectedVerboseHint = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
-                                        shouldDisplayHint.toggle()
-                                    },
-                                    label: {
-                                        HStack {
-                                            Image(systemName: "questionmark.circle")
-                                        }
-                                    }
-                                ).buttonStyle(BorderlessButtonStyle())
-                            }
-                        }.padding(.bottom)
-                    }
-                ).listRowBackground(Color.chart)
+                SettingInputSection(
+                    decimalValue: $state.maxBasal,
+                    booleanValue: $booleanPlaceholder,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Max Basal"
+                        }
+                    ),
+                    units: state.units,
+                    type: .decimal("maxBasal"),
+                    label: "Max Basal",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Max Basal… bla bla bla"
+                )
 
                 SettingInputSection(
                     decimalValue: $state.dia,

+ 2 - 2
FreeAPS/Sources/Modules/Settings/SettingItems.swift

@@ -42,7 +42,7 @@ enum SettingItems {
         SettingItem(title: "Insulin Pump", view: .pumpConfig, path: ["Devices"]),
         SettingItem(
             title: "Delivery Limits & DIA",
-            view: .cgm,
+            view: .pumpSettingsEditor,
             searchContents: ["Max Basal", "Max Bolus", "Duration of Insulin Action", "DIA"],
             path: ["Devices", "Insulin Pump", "Delivery Limits & DIA"]
         ),
@@ -107,7 +107,7 @@ enum SettingItems {
                 "Sigmoid Adjustment Factor",
                 "Weighted Average of TDD",
                 "Adjust Basal",
-                "Threshold Setting"
+                "Minimum Safety Threshold"
             ],
             path: ["Algorithm", "Dynamic Sensitivity"]
         ),

+ 1 - 6
FreeAPS/Sources/Modules/TargetsEditor/TargetsEditorStateModel.swift

@@ -7,12 +7,7 @@ extension TargetsEditor {
         let timeValues = stride(from: 0.0, to: 1.days.timeInterval, by: 30.minutes.timeInterval).map { $0 }
 
         var rateValues: [Decimal] {
-            switch units {
-            case .mgdL:
-                return stride(from: 72, to: 180.01, by: 1.0).map { $0 }
-            case .mmolL:
-                return stride(from: 4.0, to: 10.01, by: 0.1).map { $0 }
-            }
+            stride(from: 72, to: 180.01, by: 1.0).map { $0 }
         }
 
         var canAdd: Bool {

+ 5 - 2
FreeAPS/Sources/Modules/TargetsEditor/View/TargetsEditorRootView.swift

@@ -87,7 +87,10 @@ extension TargetsEditor {
                             Text(
                                 (
                                     self.rateFormatter
-                                        .string(from: state.rateValues[i] as NSNumber) ?? ""
+                                        .string(
+                                            from: state.units == .mgdL ? state.rateValues[i] as NSNumber : state.rateValues[i]
+                                                .asMmolL as NSNumber
+                                        ) ?? ""
                                 )
                                     + " \(state.units.rawValue)"
 
@@ -122,7 +125,7 @@ extension TargetsEditor {
                     NavigationLink(destination: pickers(for: index)) {
                         HStack {
                             Text(
-                                "\(rateFormatter.string(from: state.rateValues[item.lowIndex] as NSNumber) ?? "0")"
+                                "\(rateFormatter.string(from: state.units == .mgdL ? state.rateValues[item.lowIndex] as NSNumber : state.rateValues[item.lowIndex].asMmolL as NSNumber) ?? "0")"
                             )
                             Text("\(state.units.rawValue)").foregroundColor(.secondary)
                             Spacer()

+ 74 - 18
FreeAPS/Sources/Views/SettingInputSection.swift

@@ -53,18 +53,38 @@ struct SettingInputSection: View {
                                     Spacer()
 
                                     Group {
-                                        Text(
-                                            units == .mmolL ? decimalValue.asMmolL.description : decimalValue
-                                                .description
-                                        )
-                                        .foregroundColor(!displayPicker ? .primary : .accentColor)
-
                                         if setting.type == PickerSetting.PickerSettingType.glucose {
+                                            Text(
+                                                units == .mmolL ? decimalValue.asMmolL.description : decimalValue
+                                                    .description
+                                            )
+                                            .foregroundColor(!displayPicker ? .primary : .accentColor)
                                             Text(units == .mgdL ? " mg/dL" : " mmol/L").foregroundColor(.secondary)
+                                        } else if setting.type == PickerSetting.PickerSettingType.factor {
+                                            Text("\(decimalValue * 100)")
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                            Text(" %").foregroundColor(.secondary)
                                         } else if setting.type == PickerSetting.PickerSettingType.insulinUnit {
-                                            Text(" U").foregroundColor(.secondary)
+                                            Text("\(decimalValue)")
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                            Text(NSLocalizedString(" U", comment: "Insulin unit")).foregroundColor(.secondary)
                                         } else if setting.type == PickerSetting.PickerSettingType.gramms {
-                                            Text(" g").foregroundColor(.secondary)
+                                            Text("\(decimalValue)")
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                            Text(NSLocalizedString(" g", comment: "gram of carbs")).foregroundColor(.secondary)
+                                        } else if setting.type == PickerSetting.PickerSettingType.minute {
+                                            Text("\(decimalValue)")
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                            Text(" min").foregroundColor(.secondary)
+                                        } else if setting.type == PickerSetting.PickerSettingType.hour {
+                                            Text("\(decimalValue)")
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                            Text(" hr").foregroundColor(.secondary)
                                         }
                                     }.onTapGesture {
                                         displayPicker.toggle()
@@ -73,10 +93,16 @@ struct SettingInputSection: View {
 
                                 if displayPicker {
                                     Picker(selection: $decimalValue, label: Text("")) {
-                                        ForEach(pickerSettingsProvider.generatePickerValues(from: setting), id: \.self) { value in
+                                        ForEach(
+                                            pickerSettingsProvider.generatePickerValues(from: setting),
+                                            id: \.self
+                                        ) { value in
                                             if setting.type == PickerSetting.PickerSettingType.glucose {
                                                 let displayValue = units == .mgdL ? value : value.asMmolL
                                                 Text("\(displayValue.description)").tag(value)
+                                            } else if setting.type == PickerSetting.PickerSettingType.factor {
+                                                let factorValue = value * 100
+                                                Text("\(factorValue.description)").tag(value)
                                             } else {
                                                 Text("\(value.description)").tag(value)
                                             }
@@ -111,18 +137,39 @@ struct SettingInputSection: View {
                                         Spacer()
 
                                         Group {
-                                            Text(
-                                                units == .mmolL ? decimalValue.asMmolL
-                                                    .description : decimalValue.description
-                                            )
-                                            .foregroundColor(!displayPicker ? .primary : .accentColor)
-
                                             if setting.type == PickerSetting.PickerSettingType.glucose {
+                                                Text(
+                                                    units == .mmolL ? decimalValue.asMmolL.description : decimalValue
+                                                        .description
+                                                )
+                                                .foregroundColor(!displayPicker ? .primary : .accentColor)
                                                 Text(units == .mgdL ? " mg/dL" : " mmol/L").foregroundColor(.secondary)
+                                            } else if setting.type == PickerSetting.PickerSettingType.factor {
+                                                Text("\(decimalValue * 100)")
+                                                    .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                                Text(" %").foregroundColor(.secondary)
                                             } else if setting.type == PickerSetting.PickerSettingType.insulinUnit {
-                                                Text(" U").foregroundColor(.secondary)
+                                                Text("\(decimalValue)")
+                                                    .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                                Text(NSLocalizedString(" U", comment: "Insulin unit")).foregroundColor(.secondary)
                                             } else if setting.type == PickerSetting.PickerSettingType.gramms {
-                                                Text(" g").foregroundColor(.secondary)
+                                                Text("\(decimalValue)")
+                                                    .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                                Text(NSLocalizedString(" g", comment: "gram of carbs"))
+                                                    .foregroundColor(.secondary)
+                                            } else if setting.type == PickerSetting.PickerSettingType.minute {
+                                                Text("\(decimalValue)")
+                                                    .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                                Text(" min").foregroundColor(.secondary)
+                                            } else if setting.type == PickerSetting.PickerSettingType.hour {
+                                                Text("\(decimalValue)")
+                                                    .foregroundColor(!displayPicker ? .primary : .accentColor)
+
+                                                Text(" hr").foregroundColor(.secondary)
                                             }
                                         }.onTapGesture {
                                             displayConditionalPicker.toggle()
@@ -137,7 +184,10 @@ struct SettingInputSection: View {
                                             ) { value in
                                                 if setting.type == PickerSetting.PickerSettingType.glucose {
                                                     let displayValue = units == .mgdL ? value : value.asMmolL
-                                                    Text("\(displayValue.description)").tag(value)
+                                                    Text("\(displayValue.description) \(units.rawValue)").tag(value)
+                                                } else if setting.type == PickerSetting.PickerSettingType.factor {
+                                                    let factorValue = value * 100
+                                                    Text("\(factorValue.description) %").tag(value)
                                                 } else {
                                                     Text("\(value.description)").tag(value)
                                                 }
@@ -271,6 +321,12 @@ struct SettingInputSection: View {
             return pickerSettingsProvider.settings.threshold_setting
         case "updateInterval":
             return pickerSettingsProvider.settings.updateInterval
+        case "dia":
+            return pickerSettingsProvider.settings.dia
+        case "maxBolus":
+            return pickerSettingsProvider.settings.maxBolus
+        case "maxBasal":
+            return pickerSettingsProvider.settings.maxBasal
         default:
             return nil
         }