浏览代码

Battery Alarm

Jonas Björkert 1 年之前
父节点
当前提交
267b1e6b0d

+ 8 - 0
LoopFollow.xcodeproj/project.pbxproj

@@ -161,6 +161,8 @@
 		DDC7E5462DBD8A1600EB1127 /* LowBgAlarmEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC7E53E2DBD8A1600EB1127 /* LowBgAlarmEditor.swift */; };
 		DDC7E5472DBD8A1600EB1127 /* AlarmEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC7E5402DBD8A1600EB1127 /* AlarmEditor.swift */; };
 		DDC7E5CF2DC77C2000EB1127 /* SnoozerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC7E5CE2DC77C2000EB1127 /* SnoozerViewModel.swift */; };
+		DDCC3A4B2DDBB5E4006F1C10 /* BatteryCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCC3A4A2DDBB5E4006F1C10 /* BatteryCondition.swift */; };
+		DDCC3A4D2DDBB77C006F1C10 /* BatteryAlarmEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCC3A4C2DDBB77C006F1C10 /* BatteryAlarmEditor.swift */; };
 		DDCF979424C0D380002C9752 /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCF979324C0D380002C9752 /* UIViewExtension.swift */; };
 		DDCF979624C1443C002C9752 /* GeneralSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCF979524C1443C002C9752 /* GeneralSettingsViewController.swift */; };
 		DDCF979824C1489C002C9752 /* GraphSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCF979724C1489C002C9752 /* GraphSettingsViewController.swift */; };
@@ -516,6 +518,8 @@
 		DDC7E53E2DBD8A1600EB1127 /* LowBgAlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LowBgAlarmEditor.swift; sourceTree = "<group>"; };
 		DDC7E5402DBD8A1600EB1127 /* AlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmEditor.swift; sourceTree = "<group>"; };
 		DDC7E5CE2DC77C2000EB1127 /* SnoozerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnoozerViewModel.swift; sourceTree = "<group>"; };
+		DDCC3A4A2DDBB5E4006F1C10 /* BatteryCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryCondition.swift; sourceTree = "<group>"; };
+		DDCC3A4C2DDBB77C006F1C10 /* BatteryAlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryAlarmEditor.swift; sourceTree = "<group>"; };
 		DDCF979324C0D380002C9752 /* UIViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtension.swift; sourceTree = "<group>"; };
 		DDCF979524C1443C002C9752 /* GeneralSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsViewController.swift; sourceTree = "<group>"; };
 		DDCF979724C1489C002C9752 /* GraphSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphSettingsViewController.swift; sourceTree = "<group>"; };
@@ -752,6 +756,7 @@
 		DD02475A2DB2E8CE00FCADF6 /* AlarmCondition */ = {
 			isa = PBXGroup;
 			children = (
+				DDCC3A4A2DDBB5E4006F1C10 /* BatteryCondition.swift */,
 				DDB9FC7A2DDB573F00EFAA76 /* IOBCondition.swift */,
 				DDC6CA482DD8E47A0060EE25 /* PumpVolumeCondition.swift */,
 				DDC6CA442DD8D8E60060EE25 /* PumpChangeCondition.swift */,
@@ -1026,6 +1031,7 @@
 		DDC7E53F2DBD8A1600EB1127 /* Editors */ = {
 			isa = PBXGroup;
 			children = (
+				DDCC3A4C2DDBB77C006F1C10 /* BatteryAlarmEditor.swift */,
 				DDB9FC7C2DDB575300EFAA76 /* IOBAlarmEditor.swift */,
 				DDC6CA4A2DD8E4960060EE25 /* PumpVolumeAlarmEditor.swift */,
 				DDC6CA462DD8D9010060EE25 /* PumpChangeAlarmEditor.swift */,
@@ -1795,6 +1801,7 @@
 				DD7F4C252DD7B20700D449E9 /* AlarmType+timeUnit.swift in Sources */,
 				DDC7E5152DBCFA7900EB1127 /* SnoozerViewController.swift in Sources */,
 				DD7F4C072DD5042F00D449E9 /* OverrideStartAlarmEditor.swift in Sources */,
+				DDCC3A4B2DDBB5E4006F1C10 /* BatteryCondition.swift in Sources */,
 				DDDF6F492D479AF000884336 /* NoRemoteView.swift in Sources */,
 				DD0650ED2DCE9371004D3B41 /* HighBgAlarmEditor.swift in Sources */,
 				DD7F4C172DD63FA700D449E9 /* RecBolusCondition.swift in Sources */,
@@ -1879,6 +1886,7 @@
 				DDF9676E2AD08C6E00C5EB95 /* SiteChange.swift in Sources */,
 				DD13BC772C3FD64E0062313B /* InfoData.swift in Sources */,
 				DD13BC752C3FD6210062313B /* InfoType.swift in Sources */,
+				DDCC3A4D2DDBB77C006F1C10 /* BatteryAlarmEditor.swift in Sources */,
 				DDC6CA492DD8E47A0060EE25 /* PumpVolumeCondition.swift in Sources */,
 				DD1A97142D4294A5000DDC11 /* AdvancedSettingsView.swift in Sources */,
 				DD9ACA0A2D33095600415D8A /* MinAgoTask.swift in Sources */,

+ 17 - 0
LoopFollow/Alarm/AlarmCondition/BatteryCondition.swift

@@ -0,0 +1,17 @@
+// LoopFollow
+// BatteryCondition.swift
+// Created by Jonas Björkert on 2025-05-19.
+
+import Foundation
+
+struct BatteryCondition: AlarmCondition {
+    static let type: AlarmType = .battery
+    init() {}
+
+    func evaluate(alarm: Alarm, data: AlarmData, now _: Date) -> Bool {
+        guard let limit = alarm.threshold, limit > 0 else { return false }
+        guard let level = data.latestBattery else { return false }
+
+        return level <= limit
+    }
+}

+ 1 - 0
LoopFollow/Alarm/AlarmData.swift

@@ -20,6 +20,7 @@ struct AlarmData: Codable {
     let latestPumpVolume: Double?
     let IOB: Double?
     let recentBoluses: [BolusEntry]
+    let latestBattery: Double?
 }
 
 /*

+ 2 - 7
LoopFollow/Alarm/AlarmEditing/AlarmEditor.swift

@@ -2,13 +2,6 @@
 // AlarmEditor.swift
 // Created by Jonas Björkert on 2025-04-26.
 
-//
-//  AlarmEditor.swift
-//  LoopFollow
-//
-//  Created by Jonas Björkert on 2025-04-21.
-//  Copyright © 2025 Jon Fawcett. All rights reserved.
-//
 import SwiftUI
 
 struct AlarmEditor: View {
@@ -81,6 +74,8 @@ struct AlarmEditor: View {
             PumpVolumeAlarmEditor(alarm: $alarm)
         case .iob:
             IOBAlarmEditor(alarm: $alarm)
+        case .battery:
+            BatteryAlarmEditor(alarm: $alarm)
         /* TODO: add other condition types here */
         default:
             Text("No editor for \(alarm.type.rawValue)")

+ 41 - 0
LoopFollow/Alarm/AlarmEditing/Editors/BatteryAlarmEditor.swift

@@ -0,0 +1,41 @@
+// LoopFollow
+// BatteryAlarmEditor.swift
+// Created by Jonas Björkert on 2025-05-19.
+
+import SwiftUI
+
+struct BatteryAlarmEditor: View {
+    @Binding var alarm: Alarm
+
+    var body: some View {
+        Form {
+            InfoBanner(
+                text: "Alerts when the phone battery drops below the "
+                    + "percentage you set below.",
+                alarmType: alarm.type
+            )
+
+            AlarmGeneralSection(alarm: $alarm)
+
+            AlarmStepperSection(
+                header: "Battery Level",
+                footer: "Alert when remaining charge is equal to or below this.",
+                title: "Level ≤",
+                range: 0 ... 100,
+                step: 5,
+                unitLabel: "%",
+                value: Binding(
+                    get: { alarm.threshold ?? 20 },
+                    set: { alarm.threshold = $0 }
+                )
+            )
+
+            AlarmActiveSection(alarm: $alarm)
+            AlarmAudioSection(alarm: $alarm)
+            AlarmSnoozeSection(alarm: $alarm,
+                               range: 1 ... 24,
+                               step: 1)
+        }
+        .navigationTitle(alarm.type.rawValue)
+    }
+}

+ 2 - 0
LoopFollow/Alarm/AlarmManager.swift

@@ -31,6 +31,8 @@ class AlarmManager {
             PumpChangeCondition.self,
             PumpVolumeCondition.self,
             IOBCondition.self,
+            BatteryCondition.self,
+
             // TODO: add other condition types here
         ]
     ) {

+ 0 - 7
LoopFollow/Alarm/BolusEntry.swift

@@ -2,13 +2,6 @@
 // BolusEntry.swift
 // Created by Jonas Björkert on 2025-05-19.
 
-//
-//  BolusEntry.swift
-//  LoopFollow
-//
-//  Created by Jonas Björkert on 2025-05-19.
-//  Copyright © 2025 Jon Fawcett. All rights reserved.
-//
 import Foundation
 
 struct BolusEntry: Codable {

+ 0 - 1
LoopFollow/Helpers/Mobileprovision.swift

@@ -6,7 +6,6 @@
 //  MobileProvision.swift
 //  Fluux.io
 //
-//  Created by Mickaël Rémond on 03/11/2018.
 //  Copyright © 2018 ProcessOne.
 //  Distributed under Apache License v2
 //

+ 2 - 0
LoopFollow/Task/AlarmTask.swift

@@ -25,6 +25,7 @@ extension MainViewController {
             let pumpInsertTime = UserDefaultsRepository.alertCageInsertTime.value
             let latestPumpVol = self.latestPumpVolume
             let bolusEntries = self.bolusData.map { BolusEntry(units: $0.value, date: Date(timeIntervalSince1970: $0.date)) }
+            let latestBattery = UserDefaultsRepository.deviceBatteryLevel.value
 
             let alarmData = AlarmData(
                 bgReadings: self.bgData
@@ -46,6 +47,7 @@ extension MainViewController {
                 latestPumpVolume: latestPumpVol,
                 IOB: self.latestIOB?.value,
                 recentBoluses: bolusEntries,
+                latestBattery: latestBattery
             )
 
             let finalAlarmData: AlarmData