Selaa lähdekoodia

config editor update

Ivan Valkou 5 vuotta sitten
vanhempi
commit
b28b32880f

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -81,6 +81,7 @@
 		3821ED4625DC785200BC42AD /* LoopKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3821ECEC25DC723100BC42AD /* LoopKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		3821ED4725DC785700BC42AD /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3821ECF225DC723100BC42AD /* LoopKitUI.framework */; };
 		3821ED4825DC785700BC42AD /* LoopKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3821ECF225DC723100BC42AD /* LoopKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		3821ED4C25DD18BA00BC42AD /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3821ED4B25DD18BA00BC42AD /* Constants.swift */; };
 		383948D325CD4D6D00E91849 /* Disk in Frameworks */ = {isa = PBXBuildFile; productRef = 383948D225CD4D6D00E91849 /* Disk */; };
 		383948D625CD4D8900E91849 /* FileStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383948D525CD4D8900E91849 /* FileStorage.swift */; };
 		383948DA25CD64D500E91849 /* Glucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383948D925CD64D500E91849 /* Glucose.swift */; };
@@ -257,6 +258,7 @@
 		3811DF0B25CAAABD00A708ED /* APSManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APSManager.swift; sourceTree = "<group>"; };
 		3811DF0F25CAAAE200A708ED /* BaseAPSManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseAPSManager.swift; sourceTree = "<group>"; };
 		3821ECDE25DC723100BC42AD /* LoopKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = LoopKit.xcodeproj; path = LoopKit/LoopKit.xcodeproj; sourceTree = "<group>"; };
+		3821ED4B25DD18BA00BC42AD /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
 		383948D525CD4D8900E91849 /* FileStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileStorage.swift; sourceTree = "<group>"; };
 		383948D925CD64D500E91849 /* Glucose.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glucose.swift; sourceTree = "<group>"; };
 		384E803325C385E60086DB71 /* JavaScriptWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptWorker.swift; sourceTree = "<group>"; };
@@ -697,6 +699,7 @@
 				388E596B25AD95110019842D /* OpenAPS.swift */,
 				384E803325C385E60086DB71 /* JavaScriptWorker.swift */,
 				384E803725C388640086DB71 /* Script.swift */,
+				3821ED4B25DD18BA00BC42AD /* Constants.swift */,
 			);
 			path = OpenAPS;
 			sourceTree = "<group>";
@@ -967,6 +970,7 @@
 				3811DE4025C9D4A100A708ED /* SettingsBuilder.swift in Sources */,
 				3811DE0B25C9D32F00A708ED /* BaseView.swift in Sources */,
 				3811DE3225C9D49500A708ED /* HomeDataFlow.swift in Sources */,
+				3821ED4C25DD18BA00BC42AD /* Constants.swift in Sources */,
 				384E803425C385E60086DB71 /* JavaScriptWorker.swift in Sources */,
 				3811DE7A25C9D6D300A708ED /* LoginDataFlow.swift in Sources */,
 				3811DE5D25C9D4D500A708ED /* Publisher.swift in Sources */,

+ 17 - 0
FreeAPS/Resources/json/defaults/preferences.json

@@ -0,0 +1,17 @@
+{
+    "max_iob": 0,
+    "max_daily_safety_multiplier": 3,
+    "current_basal_safety_multiplier": 4,
+    "autosens_max": 1.2,
+    "autosens_min": 0.7,
+    "rewind_resets_autosens": true,
+    "adv_target_adjustments": false,
+    "exercise_mode": false,
+    "wide_bg_target_range": false,
+    "sensitivity_raises_target": true,
+    "unsuspend_if_no_temp": false,
+    "enableSMB_with_COB": false,
+    "enableSMB_with_temptarget": false,
+    "enableUAM": true,
+    "curve": "rapid-acting"
+}

+ 3 - 0
FreeAPS/Resources/json/defaults/settings/autosense.json

@@ -0,0 +1,3 @@
+{
+	"ratio": 1
+}

+ 36 - 0
FreeAPS/Sources/APS/OpenAPS/Constants.swift

@@ -0,0 +1,36 @@
+extension OpenAPS {
+    enum Bundle {
+        static let iob = "bundle/iob"
+        static let meal = "bundle/meal"
+        static let autotunePrep = "bundle/autotune-prep"
+        static let autotuneCore = "bundle/autotune-core"
+        static let getLastGlucose = "bundle/glucose-get-last"
+        static let basalSetTemp = "bundle/basal-set-temp"
+        static let determineBasal = "bundle/determine-basal"
+        static let autosens = "bundle/autosens"
+        static let profile = "bundle/profile"
+    }
+
+    enum Prepare {
+        static let iob = "prepare/iob"
+        static let meal = "prepare/meal"
+        static let autotunePrep = "prepare/autotune-prep"
+        static let autotuneCore = "prepare/autotune-core"
+        static let determineBasal = "prepare/determine-basal"
+        static let autosens = "prepare/autosens"
+        static let profile = "prepare/profile"
+    }
+
+    enum Settings {
+        static let preferences = "preferences.json"
+        static let autotune = "settings/autotune.json"
+        static let autosense = "settings/autosense.json"
+    }
+
+    enum Function {
+        static let freeaps = "freeaps"
+        static let generate = "generate"
+        static let tempBasalFunctions = "tempBasalFunctions"
+        static let exportDefaults = "exportDefaults"
+    }
+}

+ 1 - 1
FreeAPS/Sources/APS/OpenAPS/JavaScriptWorker.swift

@@ -32,7 +32,7 @@ final class JavaScriptWorker {
     }
 
     private func json(for string: String) -> RawJSON {
-        evaluate(string: "JSON.stringify(\(string));")!.toString()!
+        evaluate(string: "JSON.stringify(\(string), null, 4);")!.toString()!
     }
 
     func call(function: String, with arguments: [JSON]) -> RawJSON {

+ 1 - 35
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -38,6 +38,7 @@ final class OpenAPS {
                 temptargets: "null"
             )
             print("AUTOSENS: \(autosensResult)")
+            try? self.storage.save(autosensResult, as: Settings.autosense)
 
             let iobResult = self.iob(
                 pumphistory: pumphistory,
@@ -289,38 +290,3 @@ final class OpenAPS {
         try! String(contentsOf: Foundation.Bundle.main.url(forResource: "json/\(name)", withExtension: "json")!)
     }
 }
-
-extension OpenAPS {
-    private enum Bundle {
-        static let iob = "bundle/iob"
-        static let meal = "bundle/meal"
-        static let autotunePrep = "bundle/autotune-prep"
-        static let autotuneCore = "bundle/autotune-core"
-        static let getLastGlucose = "bundle/glucose-get-last"
-        static let basalSetTemp = "bundle/basal-set-temp"
-        static let determineBasal = "bundle/determine-basal"
-        static let autosens = "bundle/autosens"
-        static let profile = "bundle/profile"
-    }
-
-    private enum Prepare {
-        static let iob = "prepare/iob"
-        static let meal = "prepare/meal"
-        static let autotunePrep = "prepare/autotune-prep"
-        static let autotuneCore = "prepare/autotune-core"
-        static let determineBasal = "prepare/determine-basal"
-        static let autosens = "prepare/autosens"
-        static let profile = "prepare/profile"
-    }
-
-    private enum Settings {
-        static let autotune = "settings/autotune.json"
-    }
-
-    private enum Function {
-        static let freeaps = "freeaps"
-        static let generate = "generate"
-        static let tempBasalFunctions = "tempBasalFunctions"
-        static let exportDefaults = "exportDefaults"
-    }
-}

+ 7 - 0
FreeAPS/Sources/Modules/Base/BaseProvider.swift

@@ -28,4 +28,11 @@ class BaseProvider: Provider, Injectable {
             }
             .store(in: &lifetime)
     }
+
+    func defaults(for file: String) -> RawJSON {
+        guard let url = Foundation.Bundle.main.url(forResource: "json/defaults/\(file)", withExtension: "") else {
+            return ""
+        }
+        return (try? String(contentsOf: url)) ?? ""
+    }
 }

+ 14 - 1
FreeAPS/Sources/Modules/ConfigEditor/ConfigEditorBuilder.swift

@@ -1,3 +1,16 @@
+import Swinject
+
 extension ConfigEditor {
-    final class Builder: BaseModuleBuilder<RootView, ViewModel<Provider>, Provider> {}
+    final class Builder: BaseModuleBuilder<RootView, ViewModel<Provider>, Provider> {
+        private let file: String
+
+        init(resolver: Resolver, file: String) {
+            self.file = file
+            super.init(resolver: resolver)
+        }
+
+        override func buildViewModel() -> ConfigEditor.ViewModel<ConfigEditor.Provider> {
+            ViewModel(provider: Provider(resolver: resolver), resolver: resolver, file: file)
+        }
+    }
 }

+ 4 - 1
FreeAPS/Sources/Modules/ConfigEditor/ConfigEditorDataFlow.swift

@@ -2,4 +2,7 @@ enum ConfigEditor {
     enum Config {}
 }
 
-protocol ConfigEditorProvider: Provider {}
+protocol ConfigEditorProvider: Provider {
+    func save(_ value: RawJSON, as file: String)
+    func load(file: String) -> RawJSON
+}

+ 11 - 1
FreeAPS/Sources/Modules/ConfigEditor/ConfigEditorProvider.swift

@@ -1,3 +1,13 @@
 extension ConfigEditor {
-    final class Provider: BaseProvider, ConfigEditorProvider {}
+    final class Provider: BaseProvider, ConfigEditorProvider {
+        @Injected() private var storage: FileStorage!
+
+        func load(file: String) -> RawJSON {
+            (try? storage.retrieve(file, as: RawJSON.self)) ?? defaults(for: file)
+        }
+
+        func save(_ value: RawJSON, as file: String) {
+            try? storage.save(value, as: file)
+        }
+    }
 }

+ 13 - 3
FreeAPS/Sources/Modules/ConfigEditor/ConfigEditorViewModel.swift

@@ -1,16 +1,26 @@
 import SwiftUI
+import Swinject
 
 extension ConfigEditor {
     class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject where Provider: ConfigEditorProvider {
+        let file: String
         @Published var configText = ""
 
+        init(provider: Provider, resolver: Resolver, file: String) {
+            self.file = file
+            super.init(provider: provider, resolver: resolver)
+        }
+
+        required init(provider _: Provider, resolver _: Resolver) {
+            fatalError("init(provider:resolver:) has not been implemented")
+        }
+
         override func subscribe() {
-            let prefs = Preferences()
-            configText = prefs.prettyPrinted
+            configText = provider.load(file: file)
         }
 
         func save() {
-            // TODO:
+            provider.save(configText, as: file)
         }
     }
 }

+ 1 - 1
FreeAPS/Sources/Modules/ConfigEditor/View/ConfigEditorRootView.swift

@@ -10,7 +10,7 @@ extension ConfigEditor {
                 .allowsTightening(true)
                 .autocapitalization(.none)
                 .disableAutocorrection(true)
-                .toolbar { ToolbarItem(placement: .principal) { Text("preferences.json") } }
+                .toolbar { ToolbarItem(placement: .principal) { Text(viewModel.file) } }
                 .navigationBarItems(
                     leading: Button("Close", action: viewModel.hideModal),
                     trailing: Button("Save", action: viewModel.save)

+ 1 - 5
FreeAPS/Sources/Modules/Settings/SettingsViewModel.swift

@@ -1,9 +1,5 @@
 import SwiftUI
 
 extension Settings {
-    class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject where Provider: SettingsProvider {
-        func openProfileEditor() {
-            router.modalScreen.send(.configEditor)
-        }
-    }
+    class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject where Provider: SettingsProvider {}
 }

+ 2 - 1
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -6,7 +6,8 @@ extension Settings {
 
         var body: some View {
             Form {
-                Text("Open Editor").modal(for: .configEditor, from: self)
+                Text("Preferences").modal(for: .configEditor(file: OpenAPS.Settings.preferences), from: self)
+                Text("Autosense").modal(for: .configEditor(file: OpenAPS.Settings.autosense), from: self)
                 Text("Nightscout").modal(for: .nighscoutConfig, from: self)
             }
             .toolbar { ToolbarItem(placement: .principal) { Text("Settings") } }

+ 3 - 3
FreeAPS/Sources/Router/Screen.swift

@@ -8,7 +8,7 @@ enum Screen: Identifiable {
     case authorizedRoot
     case login
     case requestPermissions
-    case configEditor
+    case configEditor(file: String)
     case nighscoutConfig
 
     var id: Int { String(reflecting: self).hashValue }
@@ -29,8 +29,8 @@ extension Screen {
             return Login.Builder(resolver: resolver).buildView()
         case .requestPermissions:
             return RequestPermissions.Builder(resolver: resolver).buildView()
-        case .configEditor:
-            return ConfigEditor.Builder(resolver: resolver).buildView()
+        case let .configEditor(file):
+            return ConfigEditor.Builder(resolver: resolver, file: file).buildView()
         case .nighscoutConfig:
             return NightscoutConfig.Builder(resolver: resolver).buildView()
         }