Ivan Valkou пре 5 година
родитељ
комит
a2584fa385

+ 12 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -85,6 +85,8 @@
 		384E803825C388640086DB71 /* Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = 384E803725C388640086DB71 /* Script.swift */; };
 		3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3870FF4225EC13F40088248F /* BloodGlucose.swift */; };
 		3871F38725ED661C0013ECB5 /* Suggestion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3871F38625ED661C0013ECB5 /* Suggestion.swift */; };
+		3871F39C25ED892B0013ECB5 /* TempTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3871F39B25ED892B0013ECB5 /* TempTarget.swift */; };
+		3871F39F25ED895A0013ECB5 /* Decimal+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3871F39E25ED895A0013ECB5 /* Decimal+Extensions.swift */; };
 		388E595C25AD948C0019842D /* FreeAPSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388E595B25AD948C0019842D /* FreeAPSApp.swift */; };
 		388E596025AD948E0019842D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 388E595F25AD948E0019842D /* Assets.xcassets */; };
 		388E596C25AD95110019842D /* OpenAPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388E596B25AD95110019842D /* OpenAPS.swift */; };
@@ -139,6 +141,7 @@
 		38C4D33A25E9A1ED00D30B77 /* NSObject+AssociatedValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38C4D33925E9A1ED00D30B77 /* NSObject+AssociatedValues.swift */; };
 		38D0B3B625EBE24900CB6E88 /* Battery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D0B3B525EBE24900CB6E88 /* Battery.swift */; };
 		38D0B3D925EC07C400CB6E88 /* CarbHystoryEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D0B3D825EC07C400CB6E88 /* CarbHystoryEntry.swift */; };
+		38F3B2EF25ED8E2A005C48AA /* TempTargetsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38F3B2EE25ED8E2A005C48AA /* TempTargetsStorage.swift */; };
 		38FCF3D625E8FDF40078B0D1 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FCF3D525E8FDF40078B0D1 /* MD5.swift */; };
 		38FCF3F925E902C20078B0D1 /* FileStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FCF3F825E902C20078B0D1 /* FileStorageTests.swift */; };
 		38FCF3FD25E997A80078B0D1 /* PumpHistoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FCF3FC25E997A80078B0D1 /* PumpHistoryStorage.swift */; };
@@ -598,6 +601,8 @@
 		384E803725C388640086DB71 /* Script.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Script.swift; sourceTree = "<group>"; };
 		3870FF4225EC13F40088248F /* BloodGlucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloodGlucose.swift; sourceTree = "<group>"; };
 		3871F38625ED661C0013ECB5 /* Suggestion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Suggestion.swift; sourceTree = "<group>"; };
+		3871F39B25ED892B0013ECB5 /* TempTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempTarget.swift; sourceTree = "<group>"; };
+		3871F39E25ED895A0013ECB5 /* Decimal+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Decimal+Extensions.swift"; sourceTree = "<group>"; };
 		388E595825AD948C0019842D /* FreeAPS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FreeAPS.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		388E595B25AD948C0019842D /* FreeAPSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FreeAPSApp.swift; sourceTree = "<group>"; };
 		388E595F25AD948E0019842D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -631,6 +636,7 @@
 		38C4D33925E9A1ED00D30B77 /* NSObject+AssociatedValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+AssociatedValues.swift"; sourceTree = "<group>"; };
 		38D0B3B525EBE24900CB6E88 /* Battery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Battery.swift; sourceTree = "<group>"; };
 		38D0B3D825EC07C400CB6E88 /* CarbHystoryEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbHystoryEntry.swift; sourceTree = "<group>"; };
+		38F3B2EE25ED8E2A005C48AA /* TempTargetsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempTargetsStorage.swift; sourceTree = "<group>"; };
 		38FCF3D525E8FDF40078B0D1 /* MD5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = "<group>"; };
 		38FCF3ED25E9028E0078B0D1 /* FreeAPSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FreeAPSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		38FCF3F125E9028E0078B0D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -1080,6 +1086,7 @@
 				3870FF4225EC13F40088248F /* BloodGlucose.swift */,
 				38A0364125ED069400FCBB52 /* TempBasal.swift */,
 				3871F38625ED661C0013ECB5 /* Suggestion.swift */,
+				3871F39B25ED892B0013ECB5 /* TempTarget.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -1087,6 +1094,7 @@
 		388E5A5A25B6F05F0019842D /* Helpers */ = {
 			isa = PBXGroup;
 			children = (
+				3871F39E25ED895A0013ECB5 /* Decimal+Extensions.swift */,
 				38C4D33625E9A1A200D30B77 /* DispatchQueue+Extensions.swift */,
 				3811DE5425C9D4D500A708ED /* Formatters.swift */,
 				38B4F3AE25E2979F00E76A18 /* IndexedCollection.swift */,
@@ -1106,6 +1114,7 @@
 			children = (
 				38FCF3FC25E997A80078B0D1 /* PumpHistoryStorage.swift */,
 				38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */,
+				38F3B2EE25ED8E2A005C48AA /* TempTargetsStorage.swift */,
 			);
 			path = Storage;
 			sourceTree = "<group>";
@@ -1682,6 +1691,7 @@
 				3811DE3025C9D49500A708ED /* HomeViewModel.swift in Sources */,
 				3811DF0525CAA62600A708ED /* DependeciesContainer.swift in Sources */,
 				38BF021725E7CBBC00579895 /* PumpManagerExtensions.swift in Sources */,
+				38F3B2EF25ED8E2A005C48AA /* TempTargetsStorage.swift in Sources */,
 				3811DF1025CAAAE200A708ED /* APSManager.swift in Sources */,
 				3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */,
 				3811DE0A25C9D32F00A708ED /* BaseModuleBuilder.swift in Sources */,
@@ -1729,6 +1739,7 @@
 				3811DE0C25C9D32F00A708ED /* BaseProvider.swift in Sources */,
 				3811DE5C25C9D4D500A708ED /* Formatters.swift in Sources */,
 				3811DEC525C9D99900A708ED /* StorageContainer.swift in Sources */,
+				3871F39F25ED895A0013ECB5 /* Decimal+Extensions.swift in Sources */,
 				3811DE7F25C9D6D300A708ED /* LoginBuilder.swift in Sources */,
 				3811DE3525C9D49500A708ED /* HomeRootView.swift in Sources */,
 				3811DEC325C9D99900A708ED /* UIContainer.swift in Sources */,
@@ -1740,6 +1751,7 @@
 				3811DE2125C9D48300A708ED /* MainBuilder.swift in Sources */,
 				38FCF3D625E8FDF40078B0D1 /* MD5.swift in Sources */,
 				3811DE7925C9D6D300A708ED /* LoginViewModel.swift in Sources */,
+				3871F39C25ED892B0013ECB5 /* TempTarget.swift in Sources */,
 				3811DEAB25C9D88300A708ED /* HTTPResponseStatus.swift in Sources */,
 				3811DE5F25C9D4D500A708ED /* ProgressBar.swift in Sources */,
 				38BF021D25E7E3AF00579895 /* Reservoir.swift in Sources */,

+ 23 - 33
FreeAPS/Sources/APS/APSManager.swift

@@ -19,6 +19,7 @@ final class BaseAPSManager: APSManager, Injectable {
     @Injected() private var storage: FileStorage!
     @Injected() private var pumpHistoryStorage: PumpHistoryStorage!
     @Injected() private var glucoseStorage: GlucoseStorage!
+    @Injected() private var tempTargetsStorage: TempTargetsStorage!
     @Injected() private var keychain: Keychain!
     @Injected() private var deviceDataManager: DeviceDataManager!
     private var openAPS: OpenAPS!
@@ -28,15 +29,13 @@ final class BaseAPSManager: APSManager, Injectable {
     private var enactCancellable: AnyCancellable?
 
     var pumpManager: PumpManagerUI? {
-        get {
-            deviceDataManager.pumpManager
-        }
-        set {
-            deviceDataManager.pumpManager = newValue
-        }
+        get { deviceDataManager.pumpManager }
+        set { deviceDataManager.pumpManager = newValue }
     }
 
-    var pumpDisplayState: CurrentValueSubject<PumpDisplayState?, Never> { deviceDataManager.pumpDisplayState }
+    var pumpDisplayState: CurrentValueSubject<PumpDisplayState?, Never> {
+        deviceDataManager.pumpDisplayState
+    }
 
     init(resolver: Resolver) {
         injectServices(resolver)
@@ -47,18 +46,11 @@ final class BaseAPSManager: APSManager, Injectable {
 
     func determineBasal() {
         let now = Date()
-        guard let temp = currentTemp(date: now) else {
-            return
-        }
+        guard let temp = currentTemp(date: now) else { return }
         determineBasalCancellable = openAPS
             .determineBasal(currentTemp: temp, clock: now)
             .sink { [weak self] in
-                guard let self = self,
-                      let suggested = try? self.storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
-                else {
-                    return
-                }
-                self.enact(suggested: suggested)
+                self?.enactSuggested()
             }
     }
 
@@ -93,35 +85,33 @@ final class BaseAPSManager: APSManager, Injectable {
 
     private func currentTemp(date: Date) -> TempBasal? {
         guard let state = pumpManager?.status.basalDeliveryState else { return nil }
-        guard let lastTemp = try? storage.retrieve(OpenAPS.Monitor.tempBasal, as: TempBasal.self) else {
-            return TempBasal(duration: 0, rate: 0, temp: .absolute, updatedAt: date)
-        }
-
         switch state {
         case .active:
-            return TempBasal(duration: 0, rate: 0, temp: .absolute, updatedAt: date)
+            return TempBasal(duration: 0, rate: 0, temp: .absolute)
         case let .tempBasal(dose):
-            let doseRate = Decimal(dose.unitsPerHour)
-            if doseRate == lastTemp.rate {
-                let durationMin = Int((date.timeIntervalSince1970 - lastTemp.updatedAt.timeIntervalSince1970) / 60)
-                return TempBasal(duration: durationMin, rate: lastTemp.rate, temp: .absolute, updatedAt: date)
-            } else {
-                let durationMin = Int((date.timeIntervalSince1970 - dose.startDate.timeIntervalSince1970) / 60)
-                return TempBasal(duration: durationMin, rate: doseRate, temp: .absolute, updatedAt: date)
-            }
+            let rate = Decimal(dose.unitsPerHour)
+            let durationMin = max(0, Int((dose.endDate.timeIntervalSince1970 - date.timeIntervalSince1970) / 60))
+            return TempBasal(duration: durationMin, rate: rate, temp: .absolute)
         default: return nil
         }
     }
 
-    private func enact(suggested: Suggestion) {
-        guard let pump = pumpManager else { return }
+    private func enactSuggested() {
+        guard let pump = pumpManager,
+              let suggested = try? storage.retrieve(
+                  OpenAPS.Enact.suggested,
+                  as: Suggestion.self
+              )
+        else {
+            return
+        }
 
         enactCancellable = pump.enactTempBasal(
-            unitsPerHour: Double(truncating: suggested.rate as NSNumber),
+            unitsPerHour: Double(suggested.rate),
             for: TimeInterval(suggested.duration * 60)
         )
         .flatMap { dose -> AnyPublisher<DoseEntry, Error> in
-            let units = suggested.units.map { Double(truncating: $0 as NSNumber) } ?? 0
+            let units = suggested.units.map { Double($0) } ?? 0
             guard units > 0 else { return Just(dose).setFailureType(to: Error.self).eraseToAnyPublisher() }
             return pump.enactBolus(units: units, automatic: true)
         }

+ 4 - 4
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -16,13 +16,13 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
     func storeGlucose(_ glucose: [BloodGlucose]) {
         processQueue.async {
+            let file = OpenAPS.Monitor.glucose
             try? self.storage.transaction { storage in
-                try storage.append(glucose, to: OpenAPS.Monitor.glucose, uniqBy: \.dateString)
-                let uniqEvents = try storage.retrieve(OpenAPS.Monitor.glucose, as: [BloodGlucose].self)
+                try storage.append(glucose, to: file, uniqBy: \.dateString)
+                let uniqEvents = try storage.retrieve(file, as: [BloodGlucose].self)
                     .filter { $0.dateString.addingTimeInterval(1.days.timeInterval) > Date() }
                     .sorted { $0.dateString > $1.dateString }
-                print("[GLUCOSE] New Events\n\(uniqEvents)")
-                try storage.save(Array(uniqEvents), as: OpenAPS.Monitor.glucose)
+                try storage.save(Array(uniqEvents), as: file)
             }
         }
     }

+ 4 - 10
FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift

@@ -22,7 +22,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                 let id = event.raw.md5String
                 switch event.type {
                 case .bolus:
-                    print("[PUMP EVENT] Bolus event:\n\(event.title))")
                     guard let dose = event.dose else { return [] }
                     let amount = Decimal(string: dose.unitsInDeliverableIncrements.description)
                     let minutes = Int((dose.endDate - dose.startDate).timeInterval / 60)
@@ -38,7 +37,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         carbInput: nil
                     )]
                 case .tempBasal:
-                    print("[PUMP EVENT] Temp basal event:\n\(event.title))")
                     guard let dose = event.dose else { return [] }
                     let rate = Decimal(string: dose.unitsPerHour.description)
                     let minutes = Int((dose.endDate - dose.startDate).timeInterval / 60)
@@ -67,7 +65,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         )
                     ]
                 case .suspend:
-                    print("[PUMP EVENT] Suspend event:\n\(event.title))")
                     return [
                         PumpHistoryEvent(
                             id: id,
@@ -82,7 +79,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         )
                     ]
                 case .resume:
-                    print("[PUMP EVENT] Resume event:\n\(event.title))")
                     return [
                         PumpHistoryEvent(
                             id: id,
@@ -97,7 +93,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         )
                     ]
                 case .rewind:
-                    print("[PUMP EVENT] Rewind event:\n\(event.title))")
                     return [
                         PumpHistoryEvent(
                             id: id,
@@ -112,7 +107,6 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         )
                     ]
                 case .prime:
-                    print("[PUMP EVENT] Prime event:\n\(event.title))")
                     return [
                         PumpHistoryEvent(
                             id: id,
@@ -156,13 +150,13 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
 
     private func processNewEvents(_ events: [PumpHistoryEvent]) {
         dispatchPrecondition(condition: .onQueue(processQueue))
+        let file = OpenAPS.Monitor.pumpHistory
         try? storage.transaction { storage in
-            try storage.append(events, to: OpenAPS.Monitor.pumpHistory, uniqBy: \.id)
-            let uniqEvents = try storage.retrieve(OpenAPS.Monitor.pumpHistory, as: [PumpHistoryEvent].self)
+            try storage.append(events, to: file, uniqBy: \.id)
+            let uniqEvents = try storage.retrieve(file, as: [PumpHistoryEvent].self)
                 .filter { $0.timestamp.addingTimeInterval(1.days.timeInterval) > Date() }
                 .sorted { $0.timestamp > $1.timestamp }
-            print("[HISTORY] New Events\n\(uniqEvents)")
-            try storage.save(Array(uniqEvents), as: OpenAPS.Monitor.pumpHistory)
+            try storage.save(Array(uniqEvents), as: file)
         }
     }
 }

+ 29 - 0
FreeAPS/Sources/APS/Storage/TempTargetsStorage.swift

@@ -0,0 +1,29 @@
+import Foundation
+import SwiftDate
+import Swinject
+
+protocol TempTargetsStorage {
+    func storeTempTargets(_ targets: [TempTarget])
+}
+
+final class BaseTempTargetsStorage: TempTargetsStorage, Injectable {
+    private let processQueue = DispatchQueue(label: "BaseTempTargetsStorage.processQueue")
+    @Injected() private var storage: FileStorage!
+
+    init(resolver: Resolver) {
+        injectServices(resolver)
+    }
+
+    func storeTempTargets(_ targets: [TempTarget]) {
+        processQueue.async {
+            let file = OpenAPS.Settings.tempTargets
+            try? self.storage.transaction { storage in
+                try storage.append(targets, to: file, uniqBy: \.createdAt)
+                let uniqEvents = try storage.retrieve(file, as: [TempTarget].self)
+                    .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
+                    .sorted { $0.createdAt > $1.createdAt }
+                try storage.save(Array(uniqEvents), as: file)
+            }
+        }
+    }
+}

+ 2 - 1
FreeAPS/Sources/Containers/StorageContainer.swift

@@ -8,9 +8,10 @@ enum StorageContainer: DependeciesContainer {
         container.register(FileManager.self) { _ in
             Foundation.FileManager.default
         }
+        container.register(FileStorage.self) { _ in BaseFileStorage() }
         container.register(PumpHistoryStorage.self) { _ in BasePumpHistoryStorage(resolver: resolver) }
         container.register(GlucoseStorage.self) { _ in BaseGlucoseStorage(resolver: resolver) }
-        container.register(FileStorage.self) { _ in BaseFileStorage() }
+        container.register(TempTargetsStorage.self) { _ in BaseTempTargetsStorage(resolver: resolver) }
 
         container.register(Keychain.self) { _ in BaseKeychain() }
     }

+ 7 - 0
FreeAPS/Sources/Helpers/Decimal+Extensions.swift

@@ -0,0 +1,7 @@
+import Foundation
+
+extension Double {
+    init(_ decimal: Decimal) {
+        self.init(truncating: decimal as NSNumber)
+    }
+}

+ 2 - 2
FreeAPS/Sources/Models/CarbHystoryEntry.swift

@@ -1,14 +1,14 @@
 import Foundation
 
 struct CarbHystoryEntry: JSON {
-    let date: Date
+    let createdAt: Date
     let carbs: Int
     let enteredBy: String?
 }
 
 extension CarbHystoryEntry {
     private enum CodingKeys: String, CodingKey {
-        case date = "created_at"
+        case createdAt = "created_at"
         case carbs
         case enteredBy
     }

+ 0 - 1
FreeAPS/Sources/Models/TempBasal.swift

@@ -4,5 +4,4 @@ struct TempBasal: JSON {
     let duration: Int
     let rate: Decimal
     let temp: TempType
-    let updatedAt: Date
 }

+ 19 - 0
FreeAPS/Sources/Models/TempTarget.swift

@@ -0,0 +1,19 @@
+import Foundation
+
+struct TempTarget: JSON {
+    let id: String
+    let createdAt: Date
+    let targetTop: Int
+    let targetBottom: Int
+    let duration: Int
+}
+
+extension TempTarget {
+    private enum CodingKeys: String, CodingKey {
+        case id = "_id"
+        case createdAt = "created_at"
+        case targetTop
+        case targetBottom
+        case duration
+    }
+}

+ 3 - 3
FreeAPS/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -6,7 +6,7 @@ extension PumpConfig {
 
         var body: some View {
             Form {
-                Section(header: Text("Pump")) {
+                Section(header: Text("Model")) {
                     if let pumpState = viewModel.pumpState {
                         Button {
                             viewModel.setupPump = true
@@ -22,9 +22,9 @@ extension PumpConfig {
                     }
                 }
             }
-            .toolbar { ToolbarItem(placement: .principal) { Text("Pump Config") } }
+            .navigationTitle("Pump config")
+            .navigationBarTitleDisplayMode(.automatic)
             .navigationBarItems(leading: Button("Close", action: viewModel.hideModal))
-            .navigationBarTitleDisplayMode(.inline)
             .popover(isPresented: $viewModel.setupPump) {
                 if let pumpManager = viewModel.provider.apsManager.pumpManager {
                     PumpSettingsView(pumpManager: pumpManager, completionDelegate: viewModel)

+ 17 - 13
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -6,6 +6,14 @@ extension Settings {
 
         var body: some View {
             Form {
+                Section(header: Text("Devices")) {
+                    Text("Pump").chevronCell().modal(for: .pumpConfig, from: self)
+                }
+
+                Section(header: Text("Services")) {
+                    Text("Nightscout").chevronCell().modal(for: .nighscoutConfig, from: self)
+                }
+
                 Section(header: Text("Config files")) {
                     Group {
                         Text("Preferences").chevronCell()
@@ -20,21 +28,17 @@ extension Settings {
                         Text("Carb ratios").chevronCell().modal(for: .configEditor(file: OpenAPS.Settings.carbRatios), from: self)
                         Text("Insulin sensitivities").chevronCell()
                             .modal(for: .configEditor(file: OpenAPS.Settings.carbRatios), from: self)
+                        Text("Temp targets").chevronCell()
+                            .modal(for: .configEditor(file: OpenAPS.Settings.tempTargets), from: self)
+                        Text("Pump profile").chevronCell()
+                            .modal(for: .configEditor(file: OpenAPS.Settings.pumpProfile), from: self)
                     }
 
-                    Text("Temp targets").chevronCell().modal(for: .configEditor(file: OpenAPS.Settings.tempTargets), from: self)
-                    Text("Pump profile").chevronCell().modal(for: .configEditor(file: OpenAPS.Settings.pumpProfile), from: self)
-                    Text("Profile").chevronCell().modal(for: .configEditor(file: OpenAPS.Settings.profile), from: self)
-                    Text("Glucose").chevronCell().modal(for: .configEditor(file: OpenAPS.Monitor.glucose), from: self)
-                    Text("Meal").chevronCell().modal(for: .configEditor(file: OpenAPS.Monitor.meal), from: self)
-                }
-
-                Section(header: Text("Services")) {
-                    Text("Nightscout").chevronCell().modal(for: .nighscoutConfig, from: self)
-                }
-
-                Section(header: Text("Devices")) {
-                    Text("Pump").chevronCell().modal(for: .pumpConfig, from: self)
+                    Group {
+                        Text("Profile").chevronCell().modal(for: .configEditor(file: OpenAPS.Settings.profile), from: self)
+                        Text("Glucose").chevronCell().modal(for: .configEditor(file: OpenAPS.Monitor.glucose), from: self)
+                        Text("Meal").chevronCell().modal(for: .configEditor(file: OpenAPS.Monitor.meal), from: self)
+                    }
                 }
             }
             .navigationTitle("Settings")