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

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -93,6 +93,7 @@
 		388E5A6025B6F2310019842D /* Autosens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388E5A5F25B6F2310019842D /* Autosens.swift */; };
 		3895E4C625B9E00D00214B37 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3895E4C525B9E00D00214B37 /* Preferences.swift */; };
 		38A0363B25ECF07E00FCBB52 /* GlucoseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */; };
+		38A0364225ED069400FCBB52 /* TempBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0364125ED069400FCBB52 /* TempBasal.swift */; };
 		38A13D3225E28B4B00EAA382 /* PumpHistoryEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */; };
 		38A504A425DD9C4000C5B9E8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */; };
 		38A504A525DD9FDA00C5B9E8 /* OmniKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 38B17B2625DD6BBE005CAE3D /* OmniKit.framework */; };
@@ -606,6 +607,7 @@
 		388E5A5F25B6F2310019842D /* Autosens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Autosens.swift; sourceTree = "<group>"; };
 		3895E4C525B9E00D00214B37 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
 		38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseStorage.swift; sourceTree = "<group>"; };
+		38A0364125ED069400FCBB52 /* TempBasal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempBasal.swift; sourceTree = "<group>"; };
 		38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpHistoryEvent.swift; sourceTree = "<group>"; };
 		38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = "<group>"; };
 		38B17AAE25DD69FA005CAE3D /* SwiftCharts.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftCharts.xcodeproj; path = SwiftCharts/SwiftCharts.xcodeproj; sourceTree = "<group>"; };
@@ -1074,6 +1076,7 @@
 				38D0B3B525EBE24900CB6E88 /* Battery.swift */,
 				38D0B3D825EC07C400CB6E88 /* CarbHystoryEntry.swift */,
 				3870FF4225EC13F40088248F /* BloodGlucose.swift */,
+				38A0364125ED069400FCBB52 /* TempBasal.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -1679,6 +1682,7 @@
 				3811DF1025CAAAE200A708ED /* APSManager.swift in Sources */,
 				3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */,
 				3811DE0A25C9D32F00A708ED /* BaseModuleBuilder.swift in Sources */,
+				38A0364225ED069400FCBB52 /* TempBasal.swift in Sources */,
 				3811DE1725C9D40400A708ED /* Screen.swift in Sources */,
 				383948DA25CD64D500E91849 /* Glucose.swift in Sources */,
 				388E596C25AD95110019842D /* OpenAPS.swift in Sources */,

+ 6 - 0
FreeAPS/Resources/json/defaults/monitor/temp_basal.json

@@ -0,0 +1,6 @@
+{
+  "duration": 0,
+  "temp": "absolute",
+  "rate": 0
+}
+

+ 5 - 0
FreeAPS/Sources/APS/APSManager.swift

@@ -4,6 +4,7 @@ import LoopKitUI
 import Swinject
 
 protocol APSManager {
+    func loop()
     func runTest()
     func makeProfiles()
     var pumpManager: PumpManagerUI? { get set }
@@ -38,6 +39,10 @@ final class BaseAPSManager: APSManager, Injectable {
         openAPS = OpenAPS(storage: storage)
     }
 
+    func loop() {
+        openAPS.loop()
+    }
+
     func runTest() {
         openAPS.test()
     }

+ 11 - 2
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -139,8 +139,17 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
         )))
     }
 
-    func pumpManagerRecommendsLoop(_: PumpManager) {
-        print("[DeviceDataManager] recomends loop")
+    func pumpManagerRecommendsLoop(_ pumpManager: PumpManager) {
+        print("[DeviceDataManager] Recomends loop")
+
+        pumpManager.enactTempBasal(unitsPerHour: 0.75, for: 60.minutes.timeInterval) { result in
+            switch result {
+            case let .success(dose):
+                print("[DeviceDataManager] Temp basal OK: \(dose)")
+            case let .failure(error):
+                print("[DeviceDataManager] Temp basal FAIL: \(error.localizedDescription)")
+            }
+        }
 //        pumpManager.enactBolus(units: 0.1, automatic: true) { _ in
 //            print("[DeviceDataManager] Bolus done")
 //        }

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

@@ -46,6 +46,12 @@ extension OpenAPS {
         static let tempBasal = "monitor/temp_basal.json"
         static let meal = "monitor/meal.json"
         static let glucose = "monitor/glucose.json"
+        static let iob = "monitor/iob.json"
+    }
+
+    enum Enact {
+        static let suggested = "enact/suggested.json"
+        static let enacted = "enact/enacted.json"
     }
 
     enum Function {

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

@@ -11,6 +11,107 @@ final class OpenAPS {
         self.storage = storage
     }
 
+    func loop() {
+        processQueue.async {
+            // status
+            // check it before
+
+            // profile
+            let preferences = self.loadFileFromStorage(name: Settings.preferences)
+            let pumpSettings = self.loadFileFromStorage(name: Settings.settings)
+            let bgTargets = self.loadFileFromStorage(name: Settings.bgTargets)
+            let basalProfile = self.loadFileFromStorage(name: Settings.basalProfile)
+            let isf = self.loadFileFromStorage(name: Settings.insulinSensitivities)
+            let cr = self.loadFileFromStorage(name: Settings.carbRatios)
+            let tempTargets = self.loadFileFromStorage(name: Settings.tempTargets)
+            let model = self.loadFileFromStorage(name: Settings.model)
+            let autotune = self.loadFileFromStorage(name: Settings.autotune)
+
+            let pumpProfile = self.makeProfile(
+                preferences: preferences,
+                pumpSettings: pumpSettings,
+                bgTargets: bgTargets,
+                basalProfile: basalProfile,
+                isf: isf,
+                carbRatio: cr,
+                tempTargets: tempTargets,
+                model: model,
+                autotune: RawJSON.null
+            )
+
+            let profile = self.makeProfile(
+                preferences: preferences,
+                pumpSettings: pumpSettings,
+                bgTargets: bgTargets,
+                basalProfile: basalProfile,
+                isf: isf,
+                carbRatio: cr,
+                tempTargets: tempTargets,
+                model: model,
+                autotune: autotune.isEmpty ? .null : autotune
+            )
+
+            try? self.storage.save(pumpProfile, as: Settings.pumpProfile)
+            try? self.storage.save(profile, as: Settings.profile)
+
+            // clock
+            try? self.storage.save(Date(), as: Monitor.clock)
+
+            // temp_basal
+            let tempBasal = self.loadFileFromStorage(name: Monitor.tempBasal)
+
+            // meal
+            let pumpHistory = self.loadFileFromStorage(name: OpenAPS.Monitor.pumpHistory)
+            let carbs = self.loadFileFromStorage(name: Monitor.carbHistory)
+            let glucose = self.loadFileFromStorage(name: Monitor.glucose)
+            let clock = self.loadFileFromStorage(name: Monitor.clock)
+
+            let meal = self.meal(
+                pumphistory: pumpHistory,
+                profile: profile,
+                basalProfile: basalProfile,
+                clock: clock,
+                carbs: carbs,
+                glucose: glucose
+            )
+
+            try? self.storage.save(meal, as: Monitor.meal)
+
+            // iob
+            let autosens = self.loadFileFromStorage(name: Settings.autosense)
+            let iob = self.iob(
+                pumphistory: pumpHistory,
+                profile: profile,
+                clock: clock,
+                autosens: autosens.isEmpty ? .null : autosens,
+                pumphistory24: RawJSON.null
+            )
+
+            try? self.storage.save(iob, as: Monitor.iob)
+
+            // determine-basal
+            let glucoseStatus = self.glucoseGetLast(glucose: glucose)
+            let reservoir = self.loadFileFromStorage(name: Monitor.reservoir)
+
+            let ms = (Date(clock.rawJSON) ?? Date()).timeIntervalSince1970 * 1000
+
+            let suggested = self.determineBasal(
+                glucoseStatus: glucoseStatus,
+                currentTemp: tempBasal,
+                iob: iob,
+                profile: profile,
+                aurosens: autosens.isEmpty ? .null : autosens,
+                meal: meal,
+                microBolusAllowed: true,
+                reservoir: reservoir,
+                tsMilliseconds: ms
+            )
+            print("SUGGESTED: \(suggested)")
+
+            try? self.storage.save(suggested, as: Enact.suggested)
+        }
+    }
+
     func test() {
         processQueue.async {
             let now = Date()
@@ -255,7 +356,7 @@ final class OpenAPS {
         aurosens: JSON,
         meal: JSON,
         microBolusAllowed: Bool,
-        reservoir: Int,
+        reservoir: JSON,
         tsMilliseconds: Double
     ) -> RawJSON {
         dispatchPrecondition(condition: .onQueue(processQueue))

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

@@ -0,0 +1,8 @@
+import Foundation
+
+struct TempBasal: JSON {
+    let duration: Int
+    let rate: Decimal
+    let temp: PumpHistoryTempType
+    let updatedAt: Date
+}

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

@@ -7,6 +7,7 @@ extension ConfigEditor {
 
         var body: some View {
             TextEditor(text: $viewModel.configText)
+                .keyboardType(.asciiCapable)
                 .font(.system(.subheadline, design: .monospaced))
                 .allowsTightening(true)
                 .autocapitalization(.none)

+ 7 - 2
FreeAPS/Sources/Modules/Home/HomeViewModel.swift

@@ -3,6 +3,7 @@ import SwiftUI
 extension Home {
     class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject where Provider: HomeProvider {
         @Injected() var apsManager: APSManager!
+        @Injected() var history: PumpHistoryStorage!
 
         func runOpenAPS() {
             apsManager.runTest()
@@ -16,8 +17,12 @@ extension Home {
             apsManager.fetchLastGlucose()
         }
 
-        func makeMeal() {
-            apsManager.makeMeal()
+        func addCarbs() {
+            history.storeJournalCarbs(15)
+        }
+
+        func runLoop() {
+            apsManager.loop()
         }
     }
 }

+ 8 - 2
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -25,8 +25,14 @@ extension Home {
                         .foregroundColor(.white)
                         .buttonBackground()
                 }
-                Button(action: viewModel.makeMeal) {
-                    Text("Make meal")
+                Button(action: viewModel.addCarbs) {
+                    Text("Add 15 g carbs")
+                        .frame(maxWidth: .infinity)
+                        .foregroundColor(.white)
+                        .buttonBackground()
+                }
+                Button(action: viewModel.runLoop) {
+                    Text("Run loop")
                         .frame(maxWidth: .infinity)
                         .foregroundColor(.white)
                         .buttonBackground()