Quellcode durchsuchen

feat: add MedtrumKit

bastiaanv vor 9 Monaten
Ursprung
Commit
2a5ad66b16

+ 4 - 0
.gitmodules

@@ -41,3 +41,7 @@
 [submodule "DanaKit"]
 	path = DanaKit
 	url = https://github.com/loopandlearn/DanaKit
+[submodule "MedtrumKit"]
+	path = MedtrumKit
+	branch = dev
+	url = https://github.com/loopandlearn/MedtrumKit

+ 1 - 0
EversenseKit

@@ -0,0 +1 @@
+Subproject commit 851095c569f3673cae40358c75b10bb9ba0b6330

+ 1 - 0
MedtrumKit

@@ -0,0 +1 @@
+Subproject commit 5bfb80667c6f7f53381d07822c89dad4ee0ac60c

+ 6 - 0
Trio.xcodeproj/project.pbxproj

@@ -256,6 +256,8 @@
 		3BD6CE262DC24CFD00FA0472 /* pumphistory-24h-zoned.json in Resources */ = {isa = PBXBuildFile; fileRef = 3BD6CE252DC24CFD00FA0472 /* pumphistory-24h-zoned.json */; };
 		3BD9687C2D8DDD4600899469 /* SlideButton in Frameworks */ = {isa = PBXBuildFile; productRef = 3BD9687B2D8DDD4600899469 /* SlideButton */; };
 		3BD9687F2D8DDD8800899469 /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 3BD9687E2D8DDD8800899469 /* CryptoSwift */; };
+		3E54EF2C2E476DA40006F54D /* MedtrumKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */; };
+		3E54EF2D2E476DA40006F54D /* MedtrumKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		45252C95D220E796FDB3B022 /* ConfigEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */; };
 		45717281F743594AA9D87191 /* ConfigEditorRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 920DDB21E5D0EB813197500D /* ConfigEditorRootView.swift */; };
 		491D6FBD2D56741C00C49F67 /* TempTargetStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 491D6FBC2D56741C00C49F67 /* TempTargetStored+CoreDataProperties.swift */; };
@@ -774,6 +776,7 @@
 				3B4BA7792D8DBD690069D5B8 /* MinimedKit.framework in Embed Frameworks */,
 				CE95BF5C2BA770C300DC3DE3 /* LoopKit.framework in Embed Frameworks */,
 				3B4BA7712D8DBD690069D5B8 /* G7SensorKit.framework in Embed Frameworks */,
+				3E54EF2D2E476DA40006F54D /* MedtrumKit.framework in Embed Frameworks */,
 				CEB434FE28B90B8C00B70274 /* SwiftCharts in Embed Frameworks */,
 				3B4BA7812D8DBD690069D5B8 /* OmniKitUI.framework in Embed Frameworks */,
 				3B4BA76F2D8DBD690069D5B8 /* DanaKit.framework in Embed Frameworks */,
@@ -1074,6 +1077,7 @@
 		3BD6CE252DC24CFD00FA0472 /* pumphistory-24h-zoned.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "pumphistory-24h-zoned.json"; sourceTree = "<group>"; };
 		3BDEA2DC60EDE0A3CA54DC73 /* TargetsEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorProvider.swift; sourceTree = "<group>"; };
 		3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NightscoutConfigProvider.swift; sourceTree = "<group>"; };
+		3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MedtrumKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3F60E97100041040446F44E7 /* PumpConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpConfigStateModel.swift; sourceTree = "<group>"; };
 		3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConfigEditorDataFlow.swift; sourceTree = "<group>"; };
 		42369F66CF91F30624C0B3A6 /* BasalProfileEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BasalProfileEditorProvider.swift; sourceTree = "<group>"; };
@@ -1559,6 +1563,7 @@
 				3BD9687C2D8DDD4600899469 /* SlideButton in Frameworks */,
 				3B4BA7782D8DBD690069D5B8 /* MinimedKit.framework in Frameworks */,
 				3B4BA7762D8DBD690069D5B8 /* LibreTransmitterUI.framework in Frameworks */,
+				3E54EF2C2E476DA40006F54D /* MedtrumKit.framework in Frameworks */,
 				3B4BA7902D8DC0EC0069D5B8 /* TidepoolServiceKitUI.framework in Frameworks */,
 				3B4BA76A2D8DBD690069D5B8 /* CGMBLEKit.framework in Frameworks */,
 				3B4BA77C2D8DBD690069D5B8 /* OmniBLE.framework in Frameworks */,
@@ -2161,6 +2166,7 @@
 		3818AA48274C267000843DB3 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				3E54EF2B2E476DA40006F54D /* MedtrumKit.framework */,
 				3B4BA7882D8DC0EC0069D5B8 /* TidepoolServiceKit.framework */,
 				3B4BA7892D8DC0EC0069D5B8 /* TidepoolServiceKitUI.framework */,
 				3B4BA75B2D8DBD690069D5B8 /* CGMBLEKit.framework */,

+ 3 - 0
Trio.xcworkspace/contents.xcworkspacedata

@@ -17,6 +17,9 @@
       location = "group:DanaKit/DanaKit.xcodeproj">
    </FileRef>
    <FileRef
+      location = "group:MedtrumKit/MedtrumKit.xcodeproj">
+   </FileRef>
+   <FileRef
       location = "group:RileyLinkKit/RileyLinkKit.xcodeproj">
    </FileRef>
    <FileRef

+ 2 - 2
Trio/Resources/InfoPlist.xcstrings

@@ -8,7 +8,7 @@
         "en" : {
           "stringUnit" : {
             "state" : "new",
-            "value" : "Trio"
+            "value" : "Trio Medtrum"
           }
         }
       }
@@ -20,7 +20,7 @@
         "en" : {
           "stringUnit" : {
             "state" : "new",
-            "value" : "Trio"
+            "value" : "Trio Medtrum"
           }
         }
       }

+ 10 - 0
Trio/Sources/APS/DeviceDataManager.swift

@@ -5,6 +5,7 @@ import DanaKit
 import Foundation
 import LoopKit
 import LoopKitUI
+import MedtrumKit
 import MinimedKit
 import MockKit
 import OmniBLE
@@ -36,6 +37,7 @@ private let staticPumpManagers: [PumpManagerUI.Type] = [
     OmnipodPumpManager.self,
     OmniBLEPumpManager.self,
     DanaKitPumpManager.self,
+    MedtrumPumpManager.self,
     MockPumpManager.self
 ]
 
@@ -44,6 +46,7 @@ private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = [
     OmnipodPumpManager.pluginIdentifier: OmnipodPumpManager.self,
     OmniBLEPumpManager.pluginIdentifier: OmniBLEPumpManager.self,
     DanaKitPumpManager.pluginIdentifier: DanaKitPumpManager.self,
+    MedtrumPumpManager.pluginIdentifier: MedtrumPumpManager.self,
     MockPumpManager.pluginIdentifier: MockPumpManager.self
 ]
 
@@ -111,6 +114,13 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
                     }
                     pumpExpiresAtDate.send(endTime)
                 }
+                if let medtrum = pumpManager as? MedtrumPumpManager {
+                    guard let endTime = medtrum.state.patchExpiresAt else {
+                        pumpExpiresAtDate.send(nil)
+                        return
+                    }
+                    pumpExpiresAtDate.send(endTime)
+                }
                 if let simulatorPump = pumpManager as? MockPumpManager {
                     pumpDisplayState.value = PumpDisplayState(name: simulatorPump.localizedTitle, image: simulatorPump.smallImage)
                     pumpName.send(simulatorPump.localizedTitle)

+ 6 - 0
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -14041,6 +14041,9 @@
         }
       }
     },
+    "• Medtrum Nano (200u/300u)" : {
+
+    },
     "• Nightscout" : {
       "localizations" : {
         "bg" : {
@@ -140429,6 +140432,9 @@
         }
       }
     },
+    "Medtrum Nano" : {
+
+    },
     "Menu" : {
       "comment" : "Menu",
       "extractionState" : "manual",

+ 1 - 0
Trio/Sources/Modules/Home/View/HomeRootView.swift

@@ -951,6 +951,7 @@ extension Home {
                 Button("Omnipod Eros") { state.addPump(.omnipod) }
                 Button("Omnipod DASH") { state.addPump(.omnipodBLE) }
                 Button("Dana(RS/-i)") { state.addPump(.dana) }
+                Button("Medtrum Nano") { state.addPump(.medtrum) }
                 Button("Pump Simulator") { state.addPump(.simulator) }
             } message: { Text("Select Pump Model") }
             .sheet(isPresented: $state.shouldDisplayPumpSetupSheet) {

+ 5 - 0
Trio/Sources/Modules/Onboarding/OnboardingStateModel.swift

@@ -3,6 +3,7 @@ import DanaKit
 import FirebaseCrashlytics
 import Foundation
 import LoopKit
+import MedtrumKit
 import MinimedKit
 import Observation
 import OmniBLE
@@ -118,6 +119,8 @@ extension Onboarding {
                         defaultOption = .omnipodDash
                     } else if pumpManager is OmnipodPumpManager {
                         defaultOption = .omnipodEros
+                    } else if pumpManager is MedtrumPumpManager {
+                        defaultOption = .medtrum
                     } else if pumpManager is DanaKitPumpManager {
                         defaultOption = .dana
                     } else if pumpManager is MinimedPumpManager {
@@ -163,6 +166,8 @@ extension Onboarding {
                 return PickerSetting(value: 0.1, step: 0.05, min: 0, max: 30, type: .insulinUnitPerHour)
             case .omnipodEros:
                 return PickerSetting(value: 0.1, step: 0.05, min: 0.05, max: 30, type: .insulinUnitPerHour)
+            case .medtrum:
+                return PickerSetting(value: 0.1, step: 0.05, min: 0.05, max: 30, type: .insulinUnitPerHour)
             case .none:
                 // same as dash, as that is the fallback
                 return PickerSetting(value: 0.1, step: 0.05, min: 0, max: 30, type: .insulinUnitPerHour)

+ 2 - 1
Trio/Sources/Modules/Onboarding/View/OnboardingRootView.swift

@@ -593,7 +593,8 @@ struct OnboardingNavigationButtons: View {
                 case .dana,
                      .minimed:
                     currentAutosensSubstep = .rewindResetsAutosens
-                case .omnipodDash,
+                case .medtrum,
+                     .omnipodDash,
                      .omnipodEros:
                     currentAutosensSubstep = .autosensMax
                 }

+ 2 - 1
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/AlgorithmSettings/AlgorithmSettingsSubstepView.swift

@@ -21,7 +21,8 @@ struct AlgorithmSettingsSubstepView<Substep: AlgorithmSubstepProtocol & RawRepre
         case .dana,
              .minimed:
             return false
-        case .omnipodDash,
+        case .medtrum,
+             .omnipodDash,
              .omnipodEros:
             return true
         }

+ 3 - 0
Trio/Sources/Modules/Onboarding/View/OnboardingView+Util.swift

@@ -504,6 +504,7 @@ enum PumpOptionForOnboardingUnits: String, Equatable, CaseIterable, Identifiable
     case omnipodEros
     case omnipodDash
     case dana
+    case medtrum
 
     var id: String { rawValue }
 
@@ -517,6 +518,8 @@ enum PumpOptionForOnboardingUnits: String, Equatable, CaseIterable, Identifiable
             return "Omnipod DASH"
         case .dana:
             return "Dana (RS/-i)"
+        case .medtrum:
+            return "Medtrum Nano"
         }
     }
 }

+ 1 - 0
Trio/Sources/Modules/PumpConfig/PumpConfigDataFlow.swift

@@ -10,6 +10,7 @@ enum PumpConfig {
         case omnipod
         case omnipodBLE
         case dana
+        case medtrum
         case simulator
     }
 

+ 5 - 0
Trio/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -36,6 +36,9 @@ extension PumpConfig {
                                 } label: {
                                     HStack {
                                         Image(uiImage: pumpState.image ?? UIImage())
+                                            .resizable()
+                                            .scaledToFit()
+                                            .frame(maxWidth: 100)
                                         Text(pumpState.name)
                                     }
                                     .frame(maxWidth: .infinity, minHeight: 50, alignment: .center)
@@ -118,6 +121,7 @@ extension PumpConfig {
                                     Text("• Omnipod Eros")
                                     Text("• Omnipod DASH")
                                     Text("• Dana (RS/-i)")
+                                    Text("• Medtrum Nano (200u/300u)")
                                     Text("• Pump Simulator")
                                 }
                                 Text(
@@ -133,6 +137,7 @@ extension PumpConfig {
                     Button("Omnipod Eros") { state.addPump(.omnipod) }
                     Button("Omnipod DASH") { state.addPump(.omnipodBLE) }
                     Button("Dana(RS/-i)") { state.addPump(.dana) }
+                    Button("Medtrum Nano") { state.addPump(.medtrum) }
                     Button("Pump Simulator") { state.addPump(.simulator) }
                 } message: { Text("Select Pump Model") }
             }

+ 10 - 0
Trio/Sources/Modules/PumpConfig/View/PumpSetupView.swift

@@ -1,6 +1,7 @@
 import DanaKit
 import LoopKit
 import LoopKitUI
+import MedtrumKit
 import MinimedKit
 import MinimedKitUI
 import MockKit
@@ -68,6 +69,15 @@ extension PumpConfig {
                     prefersToSkipUserInteraction: false,
                     allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev]
                 )
+            case .medtrum:
+                setupViewController = MedtrumPumpManager.setupViewController(
+                    initialSettings: initialSettings,
+                    bluetoothProvider: bluetoothManager,
+                    colorPalette: .default,
+                    allowDebugFeatures: true,
+                    prefersToSkipUserInteraction: false,
+                    allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev]
+                )
             case .simulator:
                 setupViewController = MockPumpManager.setupViewController(
                     initialSettings: initialSettings,