Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions LoopFollow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@
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 */; };
CEAE5A1A975C4AF18ED529CB /* PumpBatteryCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BB6C97B49BC4B52B9F2838B /* PumpBatteryCondition.swift */; };
E8ECCFAF8161433BB87E672B /* PumpBatteryAlarmEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94461A074CD24360A031ACDA /* PumpBatteryAlarmEditor.swift */; };
DDCC3A4F2DDC5B54006F1C10 /* BatteryDropCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCC3A4E2DDC5B54006F1C10 /* BatteryDropCondition.swift */; };
DDCC3A542DDC5D62006F1C10 /* BatteryDropAlarmEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCC3A532DDC5D62006F1C10 /* BatteryDropAlarmEditor.swift */; };
DDCC3A562DDC9617006F1C10 /* MissedBolusCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCC3A552DDC9617006F1C10 /* MissedBolusCondition.swift */; };
Expand Down Expand Up @@ -582,6 +584,8 @@
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>"; };
2BB6C97B49BC4B52B9F2838B /* PumpBatteryCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpBatteryCondition.swift; sourceTree = "<group>"; };
94461A074CD24360A031ACDA /* PumpBatteryAlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpBatteryAlarmEditor.swift; sourceTree = "<group>"; };
DDCC3A4E2DDC5B54006F1C10 /* BatteryDropCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryDropCondition.swift; sourceTree = "<group>"; };
DDCC3A532DDC5D62006F1C10 /* BatteryDropAlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryDropAlarmEditor.swift; sourceTree = "<group>"; };
DDCC3A552DDC9617006F1C10 /* MissedBolusCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissedBolusCondition.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -839,6 +843,7 @@
DDCC3A552DDC9617006F1C10 /* MissedBolusCondition.swift */,
DDCC3A4E2DDC5B54006F1C10 /* BatteryDropCondition.swift */,
DDCC3A4A2DDBB5E4006F1C10 /* BatteryCondition.swift */,
2BB6C97B49BC4B52B9F2838B /* PumpBatteryCondition.swift */,
DDB9FC7A2DDB573F00EFAA76 /* IOBCondition.swift */,
DDC6CA482DD8E47A0060EE25 /* PumpVolumeCondition.swift */,
DDC6CA442DD8D8E60060EE25 /* PumpChangeCondition.swift */,
Expand Down Expand Up @@ -1102,6 +1107,7 @@
DDCC3A572DDC9655006F1C10 /* MissedBolusAlarmEditor.swift */,
DDCC3A532DDC5D62006F1C10 /* BatteryDropAlarmEditor.swift */,
DDCC3A4C2DDBB77C006F1C10 /* BatteryAlarmEditor.swift */,
94461A074CD24360A031ACDA /* PumpBatteryAlarmEditor.swift */,
DDB9FC7C2DDB575300EFAA76 /* IOBAlarmEditor.swift */,
DDC6CA4A2DD8E4960060EE25 /* PumpVolumeAlarmEditor.swift */,
DDC6CA462DD8D9010060EE25 /* PumpChangeAlarmEditor.swift */,
Expand Down Expand Up @@ -1920,6 +1926,7 @@
DDC7E5152DBCFA7900EB1127 /* SnoozerViewController.swift in Sources */,
DD7F4C072DD5042F00D449E9 /* OverrideStartAlarmEditor.swift in Sources */,
DDCC3A4B2DDBB5E4006F1C10 /* BatteryCondition.swift in Sources */,
CEAE5A1A975C4AF18ED529CB /* PumpBatteryCondition.swift in Sources */,
DDDF6F492D479AF000884336 /* NoRemoteView.swift in Sources */,
656F8C142E49F3D20008DC1D /* RemoteCommandSettings.swift in Sources */,
DD12D4872E1705E6004E0112 /* AlarmsContainerView.swift in Sources */,
Expand Down Expand Up @@ -2021,6 +2028,7 @@
DD13BC772C3FD64E0062313B /* InfoData.swift in Sources */,
DD13BC752C3FD6210062313B /* InfoType.swift in Sources */,
DDCC3A4D2DDBB77C006F1C10 /* BatteryAlarmEditor.swift in Sources */,
E8ECCFAF8161433BB87E672B /* PumpBatteryAlarmEditor.swift in Sources */,
DDC6CA492DD8E47A0060EE25 /* PumpVolumeCondition.swift in Sources */,
DD1A97142D4294A5000DDC11 /* AdvancedSettingsView.swift in Sources */,
DD9ACA0A2D33095600415D8A /* MinAgoTask.swift in Sources */,
Expand Down
7 changes: 6 additions & 1 deletion LoopFollow/Alarm/Alarm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ struct Alarm: Identifiable, Codable, Equatable {
soundFile = .machineCharge
delta = 10
monitoringWindow = 15
case .pumpBattery:
soundFile = .machineCharge
threshold = 20
case .recBolus:
soundFile = .dholShuffleloop
threshold = 1
Expand Down Expand Up @@ -287,7 +290,7 @@ extension AlarmType {
return .glucose
case .iob, .cob, .missedBolus, .recBolus:
return .insulin
case .battery, .batteryDrop, .pump, .pumpChange,
case .battery, .batteryDrop, .pumpBattery, .pump, .pumpChange,
.sensorChange, .notLooping, .buildExpire:
return .device
case .overrideStart, .overrideEnd, .tempTargetStart, .tempTargetEnd:
Expand All @@ -308,6 +311,7 @@ extension AlarmType {
case .recBolus: return "bolt.horizontal"
case .battery: return "battery.25"
case .batteryDrop: return "battery.100.bolt"
case .pumpBattery: return "battery.25"
case .pump: return "drop"
case .pumpChange: return "arrow.triangle.2.circlepath"
case .sensorChange: return "sensor.tag.radiowaves.forward"
Expand All @@ -334,6 +338,7 @@ extension AlarmType {
case .recBolus: return "Recommended bolus issued."
case .battery: return "Phone battery low."
case .batteryDrop: return "Battery drops quickly."
case .pumpBattery: return "Pump battery low."
case .pump: return "Reservoir level low."
case .pumpChange: return "Pump change due."
case .sensorChange: return "Sensor change due."
Expand Down
16 changes: 16 additions & 0 deletions LoopFollow/Alarm/AlarmCondition/PumpBatteryCondition.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// LoopFollow
// PumpBatteryCondition.swift

import Foundation

struct PumpBatteryCondition: AlarmCondition {
static let type: AlarmType = .pumpBattery
init() {}

func evaluate(alarm: Alarm, data: AlarmData, now _: Date) -> Bool {
guard let limit = alarm.threshold, limit > 0 else { return false }
guard let level = data.latestPumpBattery else { return false }

return level <= limit
}
}
1 change: 1 addition & 0 deletions LoopFollow/Alarm/AlarmData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct AlarmData: Codable {
let IOB: Double?
let recentBoluses: [BolusEntry]
let latestBattery: Double?
let latestPumpBattery: Double?
let batteryHistory: [DataStructs.batteryStruct]
let recentCarbs: [CarbSample]
}
1 change: 1 addition & 0 deletions LoopFollow/Alarm/AlarmEditing/AlarmEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct AlarmEditor: View {
case .iob: IOBAlarmEditor(alarm: $alarm)
case .battery: BatteryAlarmEditor(alarm: $alarm)
case .batteryDrop: BatteryDropAlarmEditor(alarm: $alarm)
case .pumpBattery: PumpBatteryAlarmEditor(alarm: $alarm)
case .missedBolus: MissedBolusAlarmEditor(alarm: $alarm)
}
}
Expand Down
33 changes: 33 additions & 0 deletions LoopFollow/Alarm/AlarmEditing/Editors/PumpBatteryAlarmEditor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// LoopFollow
// PumpBatteryAlarmEditor.swift

import SwiftUI

struct PumpBatteryAlarmEditor: View {
@Binding var alarm: Alarm

var body: some View {
Group {
InfoBanner(
text: "This warns you when the pump's battery gets low, based on the percentage you choose.",
alarmType: alarm.type
)

AlarmGeneralSection(alarm: $alarm)

AlarmStepperSection(
header: "Pump Battery Level",
footer: "This alerts you when the pump battery drops below this level.",
title: "Pump Battery Below",
range: 0 ... 100,
step: 5,
unitLabel: "%",
value: $alarm.threshold
)

AlarmActiveSection(alarm: $alarm)
AlarmAudioSection(alarm: $alarm)
AlarmSnoozeSection(alarm: $alarm)
}
}
}
1 change: 1 addition & 0 deletions LoopFollow/Alarm/AlarmManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class AlarmManager {
IOBCondition.self,
BatteryCondition.self,
BatteryDropCondition.self,
PumpBatteryCondition.self,
]
) {
var dict = [AlarmType: AlarmCondition]()
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmType/AlarmType+Snooze.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension AlarmType {
.overrideStart, .overrideEnd, .tempTargetStart,
.tempTargetEnd:
return .minute
case .battery, .batteryDrop, .sensorChange, .pumpChange, .cob, .iob,
case .battery, .batteryDrop, .pumpBattery, .sensorChange, .pumpChange, .cob, .iob,
.pump:
return .hour
case .temporary:
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmType/AlarmType+canAcknowledge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension AlarmType {
return true
// These are alarms without memory, if they only are acknowledged - they would alarm again immediately
case
.batteryDrop, .missedReading, .notLooping, .battery, .buildExpire, .iob, .sensorChange, .pumpChange, .pump:
.batteryDrop, .pumpBattery, .missedReading, .notLooping, .battery, .buildExpire, .iob, .sensorChange, .pumpChange, .pump:
return false
}
}
Expand Down
1 change: 1 addition & 0 deletions LoopFollow/Alarm/AlarmType/AlarmType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum AlarmType: String, CaseIterable, Codable {
case pump = "Pump Insulin Alert"
case battery = "Low Battery"
case batteryDrop = "Battery Drop"
case pumpBattery = "Low Pump Battery"
case recBolus = "Rec. Bolus"
case overrideStart = "Override Started"
case overrideEnd = "Override Ended"
Expand Down
11 changes: 10 additions & 1 deletion LoopFollow/Controllers/Nightscout/DeviceStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ extension MainViewController {

// NS Device Status Response Processor
func updateDeviceStatusDisplay(jsonDeviceStatus: [[String: AnyObject]]) {
infoManager.clearInfoData(types: [.iob, .cob, .battery, .pump, .target, .isf, .carbRatio, .updated, .recBolus, .tdd])
infoManager.clearInfoData(types: [.iob, .cob, .battery, .pumpBattery, .pump, .target, .isf, .carbRatio, .updated, .recBolus, .tdd])

// For Loop, clear the current override here - For Trio, it is handled using treatments
if Storage.shared.device.value == "Loop" {
Expand Down Expand Up @@ -105,6 +105,15 @@ extension MainViewController {
infoManager.updateInfoData(type: .pump, value: "50+U")
}

// Parse pump battery level
if let pumpBattery = lastPumpRecord["battery"] as? [String: AnyObject],
let percent = pumpBattery["percent"] as? Double
{
let pumpBatteryText = String(format: "%.0f", percent) + "%"
infoManager.updateInfoData(type: .pumpBattery, value: pumpBatteryText)
Observable.shared.pumpBatteryLevel.value = percent
}

if let uploader = lastDeviceStatus?["uploader"] as? [String: AnyObject],
let upbat = uploader["battery"] as? Double
{
Expand Down
3 changes: 2 additions & 1 deletion LoopFollow/InfoTable/InfoType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import Foundation

enum InfoType: Int, CaseIterable {
case iob, cob, basal, override, battery, pump, sage, cage, recBolus, minMax, carbsToday, autosens, profile, target, isf, carbRatio, updated, tdd, iage
case iob, cob, basal, override, battery, pumpBattery, pump, sage, cage, recBolus, minMax, carbsToday, autosens, profile, target, isf, carbRatio, updated, tdd, iage

var name: String {
switch self {
Expand All @@ -13,6 +13,7 @@ enum InfoType: Int, CaseIterable {
case .basal: return "Basal"
case .override: return "Override"
case .battery: return "Battery"
case .pumpBattery: return "Pump Battery"
case .pump: return "Pump"
case .sage: return "SAGE"
case .cage: return "CAGE"
Expand Down
1 change: 1 addition & 0 deletions LoopFollow/Storage/Observable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Observable {
var alertLastLoopTime = ObservableValue<TimeInterval?>(default: nil)
var deviceRecBolus = ObservableValue<Double?>(default: nil)
var deviceBatteryLevel = ObservableValue<Double?>(default: nil)
var pumpBatteryLevel = ObservableValue<Double?>(default: nil)

var settingsPath = ObservableValue<NavigationPath>(default: NavigationPath())

Expand Down
2 changes: 2 additions & 0 deletions LoopFollow/Task/AlarmTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extension MainViewController {
let latestPumpVol = self.latestPumpVolume
let bolusEntries = self.bolusData.map { BolusEntry(units: $0.value, date: Date(timeIntervalSince1970: $0.date)) }
let latestBattery = Observable.shared.deviceBatteryLevel.value
let latestPumpBattery = Observable.shared.pumpBatteryLevel.value
let recentCarbs: [CarbSample] = self.carbData.map { CarbSample(grams: $0.value, date: Date(timeIntervalSince1970: $0.date)) }

let alarmData = AlarmData(
Expand All @@ -49,6 +50,7 @@ extension MainViewController {
IOB: self.latestIOB?.value,
recentBoluses: bolusEntries,
latestBattery: latestBattery,
latestPumpBattery: latestPumpBattery,
batteryHistory: self.deviceBatteryData,
recentCarbs: recentCarbs
)
Expand Down