Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved remote meal #84

Merged
merged 17 commits into from
Jun 2, 2024
Merged
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
162 changes: 104 additions & 58 deletions LoopFollow/Application/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions LoopFollow/Controllers/Graphs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ extension MainViewController {
lineResume.drawValuesEnabled = false


// Sensor Change
// Sensor Start
var chartEntrySensor = [ChartDataEntry]()
let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
lineSensor.circleRadius = CGFloat(globalVariables.dotOther)
Expand Down Expand Up @@ -383,10 +383,10 @@ extension MainViewController {
let chartEntryNote = [ChartDataEntry]()
let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
lineNote.circleRadius = CGFloat(globalVariables.dotOther)
lineNote.circleColors = [NSUIColor.white.withAlphaComponent(0.75)]
lineNote.circleColors = [NSUIColor.systemGray2.withAlphaComponent(0.75)]
lineNote.drawCircleHoleEnabled = false
lineNote.setDrawHighlightIndicators(false)
lineNote.setColor(NSUIColor.white, alpha: 1.0)
lineNote.setColor(NSUIColor.systemGray2, alpha: 1.0)
lineNote.drawCirclesEnabled = true
lineNote.lineWidth = 0
lineNote.highlightEnabled = true
Expand Down Expand Up @@ -1369,11 +1369,11 @@ extension MainViewController {
}
}

func updateSensorChange() {
func updateSensorStart() {
var dataIndex = 10
BGChart.lineData?.dataSets[dataIndex].clear()
BGChartFull.lineData?.dataSets[dataIndex].clear()
let thisData = sensorChangeGraphData
let thisData = sensorStartGraphData
for i in 0..<thisData.count{
// skip if outside of visible area
let graphHours = 24 * UserDefaultsRepository.downloadDays.value
Expand Down Expand Up @@ -1685,7 +1685,7 @@ extension MainViewController {
lineResume.valueFormatter = ChartYDataValueFormatter()
lineResume.drawValuesEnabled = false

// Sensor Change
// Sensor Start
var chartEntrySensor = [ChartDataEntry]()
let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
lineSensor.circleRadius = 2
Expand Down Expand Up @@ -1719,10 +1719,10 @@ extension MainViewController {
var chartEntryNote = [ChartDataEntry]()
let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
lineNote.circleRadius = 2
lineNote.circleColors = [NSUIColor.systemGray.withAlphaComponent(0.75)]
lineNote.circleColors = [NSUIColor.systemGray2.withAlphaComponent(0.75)]
lineNote.drawCircleHoleEnabled = false
lineNote.setDrawHighlightIndicators(false)
lineNote.setColor(NSUIColor.systemGray3, alpha: 1.0)
lineNote.setColor(NSUIColor.systemGray2, alpha: 1.0)
lineNote.drawCirclesEnabled = true
lineNote.lineWidth = 0
lineNote.highlightEnabled = false
Expand Down
4 changes: 2 additions & 2 deletions LoopFollow/Controllers/NightScout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ extension MainViewController {

func clearOldSensor()
{
sensorChangeGraphData.removeAll()
updateSensorChange()
sensorStartGraphData.removeAll()
updateSensorStart()
}

func clearOldPump()
Expand Down
63 changes: 39 additions & 24 deletions LoopFollow/Controllers/Nightscout/CAge.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
//
// CAge.swift
// LoopFollow
//
// Created by Jonas Björkert on 2023-10-05.
// Copyright © 2023 Jon Fawcett. All rights reserved.
//

import Foundation

extension MainViewController {
// NS Cage Web Call
func webLoadNSCage() {
Expand Down Expand Up @@ -44,28 +37,50 @@ extension MainViewController {
.withTime,
.withDashSeparatorInDate,
.withColonSeparatorInTime]
UserDefaultsRepository.alertCageInsertTime.value = formatter.date(from: (lastCageString))?.timeIntervalSince1970 as! TimeInterval
if let cageTime = formatter.date(from: (lastCageString))?.timeIntervalSince1970 {
if let cageTime = formatter.date(from: lastCageString)?.timeIntervalSince1970 {
UserDefaultsRepository.alertCageInsertTime.value = cageTime

let now = dateTimeUtils.getNowTimeIntervalUTC()
let secondsAgo = now - cageTime
//let days = 24 * 60 * 60

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
formatter.allowedUnits = [ .day, .hour ] // Units to display in the formatted string
formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale

// Set maximumUnitCount to 0 to include all available units
formatter.maximumUnitCount = 0
let oldFormatter = DateComponentsFormatter()
oldFormatter.unitsStyle = .positional
oldFormatter.allowedUnits = [.day, .hour]
oldFormatter.zeroFormattingBehavior = [.pad]
oldFormatter.maximumUnitCount = 0

if let formattedDuration = formatter.string(from: secondsAgo) {
// Manually add spaces between the number and units
let spacedDuration = formattedDuration
.replacingOccurrences(of: "d", with: " d")
.replacingOccurrences(of: "h", with: " h")
if let formattedDuration = oldFormatter.string(from: secondsAgo) {
let spacedDuration = formattedDuration
.replacingOccurrences(of: "d", with: " d")
.replacingOccurrences(of: "h", with: " h")

tableData[7].value = spacedDuration
//tableData[7].value = spacedDuration
}

// Add 3 days to cageTime
let threeDaysLater = cageTime + 3 * 24 * 60 * 60

// Calculate the remaining time
let timeRemaining = threeDaysLater - now

// Extract the components
let daysRemaining = Int(timeRemaining / (24 * 60 * 60))
let hoursRemaining = Int((timeRemaining.truncatingRemainder(dividingBy: 24 * 60 * 60)) / (60 * 60))
let minutesRemaining = Int((timeRemaining.truncatingRemainder(dividingBy: 60 * 60)) / 60)

// Construct the string manually
var spacedRemainingDuration = ""
if daysRemaining > 0 {
spacedRemainingDuration += "\(daysRemaining)d "
}
if hoursRemaining > 0 || daysRemaining > 0 {
spacedRemainingDuration += "\(hoursRemaining)h "
}
if daysRemaining == 0 {
spacedRemainingDuration += "\(minutesRemaining)m"
}
// Update tableData[70].value with the remaining duration
tableData[7].value = spacedRemainingDuration
}
infoTable.reloadData()
}
Expand Down
50 changes: 29 additions & 21 deletions LoopFollow/Controllers/Nightscout/DeviceStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -483,35 +483,31 @@ extension MainViewController {
}

var predictionColor = UIColor.systemGray
PredictionLabel.textColor = predictionColor

if let eventualData = lastLoopRecord["suggested"] as? [String: Any],
let eventualBGValue = eventualData["eventualBG"] as? NSNumber,
let loopYellow = UIColor(named: "LoopYellow"),
let loopRed = UIColor(named: "LoopRed"),
let loopGreen = UIColor(named: "LoopGreen") {

let eventualBGValue = eventualData["eventualBG"] as? NSNumber,
let loopYellow = UIColor(named: "LoopYellow"),
let loopRed = UIColor(named: "LoopRed"),
let loopGreen = UIColor(named: "LoopGreen") {
let eventualBGFloatValue = eventualBGValue.floatValue // Convert NSNumber to Float

let eventualBGStringValue = String(describing: eventualBGValue)
let formattedBGString = bgUnits.toDisplayUnits(eventualBGStringValue).replacingOccurrences(of: ",", with: ".")
PredictionLabel.text = " Prognos ⇢ \(formattedBGString)"

// Print statements for debugging
//print("eventualBGValue:", eventualBGFloatValue)
//print("High Line Value:", UserDefaultsRepository.highLine.value)
//print("Low Line Value:", UserDefaultsRepository.lowLine.value)

if eventualBGFloatValue >= UserDefaultsRepository.highLine.value {
PredictionLabel.text = " Prognos ⇢ \(formattedBGString)"
PredictionLabel.textColor = loopYellow
predictionColor = loopYellow
} else if eventualBGFloatValue <= UserDefaultsRepository.lowLine.value {
PredictionLabel.text = " Prognos ⇢ \(formattedBGString)"
PredictionLabel.textColor = loopRed
predictionColor = loopRed
} else if eventualBGFloatValue > UserDefaultsRepository.lowLine.value && eventualBGFloatValue < UserDefaultsRepository.highLine.value {
PredictionLabel.text = " Prognos ⇢ \(formattedBGString)"
PredictionLabel.textColor = loopGreen
predictionColor = loopGreen
}

// Debug print for the selected color
//print("Selected Prediction Color:", predictionColor)
}

// Update PredictionLabel with the new color
Expand Down Expand Up @@ -541,21 +537,33 @@ extension MainViewController {
latestLoopStatusString = "⏀"
if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Open Loop: recommended temp. temp time > bg time, was not enacted") }
} else {
LoopStatusLabel.text = " "
latestLoopStatusString = ""
LoopStatusLabel.text = " "
latestLoopStatusString = ""
if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Looping: recommended temp, but temp time is < bg time and/or was enacted") }
}
}
} else if let enacted = lastLoopRecord["enacted"] as? [String: AnyObject],
let received = enacted["recieved"] as? Bool, !received {
// Daniel: If "recieved" is false, it means there's a failure. received is misspelled as recieved in iAPS upload to NS Device status
LoopStatusLabel.text = " ᮰"
LoopStatusLabel.textColor = UIColor(named: "LoopYellow")
latestLoopStatusString = "᮰"
if UserDefaultsRepository.debugLog.value {
self.writeDebugLog(value: "iAPS Not Enacted: X")
}
} else {
LoopStatusLabel.text = " ↻"
latestLoopStatusString = "↻"
LoopStatusLabel.text = " ᮰"
LoopStatusLabel.textColor = UIColor(named: "LoopGreen")
latestLoopStatusString = "᮰"
if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Looping: no recommended temp") }
print("Looping: no recommended temp")
}

}
if ((TimeInterval(Date().timeIntervalSince1970) - lastLoopTime) / 60) > 15 {
LoopStatusLabel.text = " ⚠️"
latestLoopStatusString = "⚠"
LoopStatusLabel.text = " ᮰"
LoopStatusLabel.textColor = UIColor(named: "LoopRed")
latestLoopStatusString = "᮰"

}
latestLoopTime = lastLoopTime
Expand Down
3 changes: 3 additions & 0 deletions LoopFollow/Controllers/Nightscout/Profile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ extension MainViewController {
let startDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: Double(timeStart + (60 * 5)))
basalScheduleData.append(startDot)

basalNow = String(format:"%.2f", basalSegments[i].basalRate)
print("Basalnow \(basalNow)")

// set the enddot where the next one will start
var endDate = basalSegments[i].endDate
let endDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: endDate)
Expand Down
82 changes: 50 additions & 32 deletions LoopFollow/Controllers/Nightscout/SAge.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
//
// SAGE.swift
// LoopFollow
//
// Created by Jonas Björkert on 2023-10-05.
// Copyright © 2023 Jon Fawcett. All rights reserved.
//

import Foundation

extension MainViewController {
// NS Sage Web Call
func webLoadNSSage() {
Expand Down Expand Up @@ -40,45 +33,70 @@ extension MainViewController {
return
}
currentSage = data[0]
var lastSageString = data[0].created_at
let lastSageString = data[0].created_at

let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withFullDate,
.withTime,
.withDashSeparatorInDate,
.withColonSeparatorInTime]
UserDefaultsRepository.alertSageInsertTime.value = formatter.date(from: (lastSageString))?.timeIntervalSince1970 as! TimeInterval

if UserDefaultsRepository.alertAutoSnoozeCGMStart.value && (dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertSageInsertTime.value < 7200){
let snoozeTime = Date(timeIntervalSince1970: UserDefaultsRepository.alertSageInsertTime.value + 7200)
UserDefaultsRepository.alertSnoozeAllTime.value = snoozeTime
UserDefaultsRepository.alertSnoozeAllIsSnoozed.value = true
guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
alarms.reloadIsSnoozed(key: "alertSnoozeAllIsSnoozed", value: true)
alarms.reloadSnoozeTime(key: "alertSnoozeAllTime", setNil: false, value: snoozeTime)
}

if let sageTime = formatter.date(from: (lastSageString as! String))?.timeIntervalSince1970 {
if let sageTime = formatter.date(from: lastSageString)?.timeIntervalSince1970 {
UserDefaultsRepository.alertSageInsertTime.value = sageTime
if UserDefaultsRepository.alertAutoSnoozeCGMStart.value && (dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertSageInsertTime.value < 7200) {
let snoozeTime = Date(timeIntervalSince1970: UserDefaultsRepository.alertSageInsertTime.value + 7200)
UserDefaultsRepository.alertSnoozeAllTime.value = snoozeTime
UserDefaultsRepository.alertSnoozeAllIsSnoozed.value = true
guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
alarms.reloadIsSnoozed(key: "alertSnoozeAllIsSnoozed", value: true)
alarms.reloadSnoozeTime(key: "alertSnoozeAllTime", setNil: false, value: snoozeTime)
}
let now = dateTimeUtils.getNowTimeIntervalUTC()
let secondsAgo = now - sageTime
let days = 24 * 60 * 60

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
formatter.allowedUnits = [ .day, .hour] // Units to display in the formatted string
formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale
let oldFormatter = DateComponentsFormatter()
oldFormatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
oldFormatter.allowedUnits = [ .day, .hour] // Units to display in the formatted string
oldFormatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale

// Set maximumUnitCount to 0 to include all available units
formatter.maximumUnitCount = 0
oldFormatter.maximumUnitCount = 0

if let formattedDuration = formatter.string(from: secondsAgo) {
// Manually add spaces between the number and units
let spacedDuration = formattedDuration
.replacingOccurrences(of: "d", with: " d")
.replacingOccurrences(of: "h", with: " h")
if let formattedDuration = oldFormatter.string(from: secondsAgo) {
// Manually add spaces between the number and units
let spacedDuration = formattedDuration
.replacingOccurrences(of: "d", with: " d")
.replacingOccurrences(of: "h", with: " h")

tableData[6].value = spacedDuration
//tableData[6].value = spacedDuration
}

// Add 10 days to sageTime
let tenDaysLater = sageTime + 10 * 24 * 60 * 60

// Calculate the remaining time
let timeRemaining = tenDaysLater - now

// Extract the components
let daysRemaining = Int(timeRemaining / (24 * 60 * 60))
let hoursRemaining = Int((timeRemaining.truncatingRemainder(dividingBy: 24 * 60 * 60)) / (60 * 60))
let minutesRemaining = Int((timeRemaining.truncatingRemainder(dividingBy: 60 * 60)) / 60)

// Construct the string manually
var spacedRemainingDuration = ""
if daysRemaining > 0 {
spacedRemainingDuration += "\(daysRemaining)d "
}
if hoursRemaining > 0 || daysRemaining > 0 {
spacedRemainingDuration += "\(hoursRemaining)h "
}
if daysRemaining == 0 {
spacedRemainingDuration += "\(minutesRemaining)m"
}
// Update tableData[60].value with the remaining duration
tableData[6].value = spacedRemainingDuration
}
infoTable.reloadData()
}
Expand Down
Loading