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

Info Table improvements #318

Merged
merged 7 commits into from
Jul 18, 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
68 changes: 62 additions & 6 deletions LoopFollow.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions LoopFollow/Controllers/Alarms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ extension MainViewController {
}
if bolusCount >= UserDefaultsRepository.alertIOBNumber.value ||
totalBoluses >= Double(UserDefaultsRepository.alertIOBMaxBoluses.value) ||
Double(latestIOB) ?? 0 >= Double(UserDefaultsRepository.alertIOBMaxBoluses.value) {
(latestIOB?.value ?? 0) >= Double(UserDefaultsRepository.alertIOBMaxBoluses.value) {
AlarmSound.whichAlarm = "IOB Alert"
//determine if it is day or night and what should happen
if UserDefaultsRepository.nightTime.value {
Expand All @@ -104,7 +104,7 @@ extension MainViewController {
// Check COB
if UserDefaultsRepository.alertCOB.value && !UserDefaultsRepository.alertCOBIsSnoozed.value {
let alertAt = Double(UserDefaultsRepository.alertCOBAt.value)
if Double(latestCOB) ?? 0 >= alertAt {
if (latestCOB?.value ?? 0) >= alertAt {
AlarmSound.whichAlarm = "COB Alert"
//determine if it is day or night and what should happen
if UserDefaultsRepository.nightTime.value {
Expand Down Expand Up @@ -586,7 +586,7 @@ extension MainViewController {
if !UserDefaultsRepository.alertAudioDuringPhone.value && isOnPhoneCall() { audioDuringCall = false }

guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
snoozer.updateDisplayWhenTriggered(bgVal: bgUnits.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: bgUnits.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
snoozer.updateDisplayWhenTriggered(bgVal: Localizer.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: Localizer.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
if audio && !UserDefaultsRepository.alertMuteAllIsMuted.value && audioDuringCall{
AlarmSound.setSoundFile(str: sound)
AlarmSound.play(overrideVolume: overrideVolume, numLoops: numLoops)
Expand All @@ -600,7 +600,7 @@ extension MainViewController {
if !UserDefaultsRepository.alertAudioDuringPhone.value && isOnPhoneCall() { audioDuringCall = false }

guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
snoozer.updateDisplayWhenTriggered(bgVal: bgUnits.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: bgUnits.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
snoozer.updateDisplayWhenTriggered(bgVal: Localizer.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: Localizer.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
snoozer.SnoozeButton.isHidden = false
snoozer.AlertLabel.isHidden = false
snoozer.clockLabel.isHidden = true
Expand Down Expand Up @@ -633,7 +633,7 @@ extension MainViewController {

AlarmSound.whichAlarm = "none"
guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
snoozer.updateDisplayWhenTriggered(bgVal: bgUnits.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: bgUnits.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
snoozer.updateDisplayWhenTriggered(bgVal: Localizer.toDisplayUnits(String(bgData[bgData.count - 1].sgv)), directionVal: latestDirectionString ?? "", deltaVal: Localizer.toDisplayUnits(latestDeltaString) ?? "", minAgoVal: latestMinAgoString ?? "", alertLabelVal: AlarmSound.whichAlarm)
snoozer.SnoozeButton.isHidden = true
snoozer.AlertLabel.isHidden = true
if AlarmSound.isPlaying {
Expand Down Expand Up @@ -1026,14 +1026,14 @@ extension MainViewController {
let texts = AnnouncementTexts.forLanguage(preferredLanguage)

let negligibleThreshold = 3
let localizedCurrentValue = bgUnits.toDisplayUnits(String(currentValue)).replacingOccurrences(of: ",", with: ".")
let localizedCurrentValue = Localizer.toDisplayUnits(String(currentValue)).replacingOccurrences(of: ",", with: ".")
let announcementText: String

if abs(bloodGlucoseDifference) <= negligibleThreshold {
announcementText = "\(texts.currentBGIs) \(localizedCurrentValue) \(texts.stable)"
} else {
let directionText = bloodGlucoseDifference < 0 ? texts.decrease : texts.increase
let absoluteDifference = bgUnits.toDisplayUnits(String(abs(bloodGlucoseDifference))).replacingOccurrences(of: ",", with: ".")
let absoluteDifference = Localizer.toDisplayUnits(String(abs(bloodGlucoseDifference))).replacingOccurrences(of: ",", with: ".")
announcementText = "\(texts.currentBGIs) \(localizedCurrentValue) \(directionText) \(absoluteDifference)"
}

Expand Down
8 changes: 4 additions & 4 deletions LoopFollow/Controllers/Graphs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ extension MainViewController {
if Float(entries[i].sgv) > topBG - maxBGOffset {
topBG = Float(entries[i].sgv) + maxBGOffset
}
let value = ChartDataEntry(x: Double(entries[i].date), y: Double(entries[i].sgv), data: formatPillText(line1: bgUnits.toDisplayUnits(String(entries[i].sgv)), time: entries[i].date))
let value = ChartDataEntry(x: Double(entries[i].date), y: Double(entries[i].sgv), data: formatPillText(line1: Localizer.toDisplayUnits(String(entries[i].sgv)), time: entries[i].date))
if UserDefaultsRepository.debugLog.value { writeDebugLog(value: "BG: " + value.description) }
mainChart.append(value)
smallChart.append(value)
Expand Down Expand Up @@ -731,7 +731,7 @@ extension MainViewController {
colors.append(color ?? NSUIColor.systemPurple)
}

let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal, data: formatPillText(line1: bgUnits.toDisplayUnits(String(predictionData[i].sgv)), time: predictionData[i].date))
let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal, data: formatPillText(line1: Localizer.toDisplayUnits(String(predictionData[i].sgv)), time: predictionData[i].date))
mainChart.addEntry(value)
smallChart.addEntry(value)
}
Expand Down Expand Up @@ -1025,7 +1025,7 @@ extension MainViewController {
let graphHours = 24 * UserDefaultsRepository.downloadDays.value
if bgCheckData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }

let value = ChartDataEntry(x: Double(bgCheckData[i].date), y: Double(bgCheckData[i].sgv), data: formatPillText(line1: bgUnits.toDisplayUnits(String(bgCheckData[i].sgv)), time: bgCheckData[i].date))
let value = ChartDataEntry(x: Double(bgCheckData[i].date), y: Double(bgCheckData[i].sgv), data: formatPillText(line1: Localizer.toDisplayUnits(String(bgCheckData[i].sgv)), time: bgCheckData[i].date))
BGChart.data?.dataSets[dataIndex].addEntry(value)
if UserDefaultsRepository.smallGraphTreatments.value {
BGChartFull.data?.dataSets[dataIndex].addEntry(value)
Expand Down Expand Up @@ -1573,7 +1573,7 @@ extension MainViewController {
data: formatPillText(
line1: chartLabel,
time: predictionData[i].date,
line2: bgUnits.toDisplayUnits(String(predictionVal))
line2: Localizer.toDisplayUnits(String(predictionVal))
)
)
mainChart.addEntry(value)
Expand Down
18 changes: 1 addition & 17 deletions LoopFollow/Controllers/NightScout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,13 @@ extension MainViewController {
var created_at: String
}


//NS Basal Profile Struct
struct basalProfileStruct: Codable {
var value: Double
var time: String
var timeAsSeconds: Double
}

struct NSProfile: Decodable {
struct Store: Decodable {
struct BasalEntry: Decodable {
let value: Double
let time: String
let timeAsSeconds: Double
}

let basal: [BasalEntry]
}

let store: [String: Store]
let defaultProfile: String
}


//NS Basal Data Struct
struct basalGraphStruct: Codable {
var basalRate: Double
Expand Down
12 changes: 6 additions & 6 deletions LoopFollow/Controllers/Nightscout/BGData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ extension MainViewController {
var snoozerDelta = ""

// Set BGText with the latest BG value
self.BGText.text = bgUnits.toDisplayUnits(String(latestBG))
snoozerBG = bgUnits.toDisplayUnits(String(latestBG))
self.BGText.text = Localizer.toDisplayUnits(String(latestBG))
snoozerBG = Localizer.toDisplayUnits(String(latestBG))
self.setBGTextColor()

// Direction handling
Expand All @@ -256,12 +256,12 @@ extension MainViewController {

// Delta handling
if deltaBG < 0 {
self.DeltaText.text = bgUnits.toDisplayUnits(String(deltaBG))
snoozerDelta = bgUnits.toDisplayUnits(String(deltaBG))
self.DeltaText.text = Localizer.toDisplayUnits(String(deltaBG))
snoozerDelta = Localizer.toDisplayUnits(String(deltaBG))
self.latestDeltaString = String(deltaBG)
} else {
self.DeltaText.text = "+" + bgUnits.toDisplayUnits(String(deltaBG))
snoozerDelta = "+" + bgUnits.toDisplayUnits(String(deltaBG))
self.DeltaText.text = "+" + Localizer.toDisplayUnits(String(deltaBG))
snoozerDelta = "+" + Localizer.toDisplayUnits(String(deltaBG))
self.latestDeltaString = "+" + String(deltaBG)
}

Expand Down
8 changes: 4 additions & 4 deletions LoopFollow/Controllers/Nightscout/CAge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension MainViewController {

// NS Cage Response Processor
func updateCage(data: [cageData]) {
self.clearLastInfoData(index: 7)
infoManager.clearInfoData(type: .cage)
if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: CAGE") }
if data.count == 0 {
return
Expand All @@ -55,9 +55,9 @@ extension MainViewController {
formatter.allowedUnits = [ .day, .hour ] // Units to display in the formatted string
formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale

let formattedDuration = formatter.string(from: secondsAgo)
tableData[7].value = formattedDuration ?? ""
if let formattedDuration = formatter.string(from: secondsAgo) {
infoManager.updateInfoData(type: .cage, value: formattedDuration)
}
}
infoTable.reloadData()
}
}
48 changes: 22 additions & 26 deletions LoopFollow/Controllers/Nightscout/DeviceStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,8 @@ extension MainViewController {

// NS Device Status Response Processor
func updateDeviceStatusDisplay(jsonDeviceStatus: [[String:AnyObject]]) {
self.clearLastInfoData(index: 0)
self.clearLastInfoData(index: 1)
self.clearLastInfoData(index: 3)
self.clearLastInfoData(index: 4)
self.clearLastInfoData(index: 5)
infoManager.clearInfoData(types: [.iob, .cob, .override, .battery, .pump, .target, .isf, .carbRatio, .updated, .recBolus, .tdd])

if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: device status") }
if jsonDeviceStatus.count == 0 {
return
Expand All @@ -106,15 +103,15 @@ extension MainViewController {
if let lastPumpTime = formatter.date(from: (lastPumpRecord["clock"] as! String))?.timeIntervalSince1970 {
if let reservoirData = lastPumpRecord["reservoir"] as? Double {
latestPumpVolume = reservoirData
tableData[5].value = String(format:"%.0f", reservoirData) + "U"
infoManager.updateInfoData(type: .pump, value: String(format: "%.0f", reservoirData) + "U")
} else {
latestPumpVolume = 50.0
tableData[5].value = "50+U"
infoManager.updateInfoData(type: .pump, value: "50+U")
}
if let uploader = lastDeviceStatus?["uploader"] as? [String:AnyObject] {
let upbat = uploader["battery"] as! Double
tableData[4].value = String(format:"%.0f", upbat) + "%"

if let uploader = lastDeviceStatus?["uploader"] as? [String: AnyObject],
let upbat = uploader["battery"] as? Double {
infoManager.updateInfoData(type: .battery, value: String(format: "%.0f", upbat) + "%")
UserDefaultsRepository.deviceBatteryLevel.value = upbat
}
}
Expand All @@ -130,31 +127,30 @@ extension MainViewController {
DeviceStatusOpenAPS(formatter: formatter, lastDeviceStatus: lastDeviceStatus, lastLoopRecord: lastLoopRecord)
}

var oText = "" as String
var oText = ""
currentOverride = 1.0
if let lastOverride = lastDeviceStatus?["override"] as! [String : AnyObject]? {
if lastOverride["active"] as! Bool {
if let lastOverride = lastDeviceStatus?["override"] as? [String: AnyObject],
let isActive = lastOverride["active"] as? Bool, isActive {
if let lastCorrection = lastOverride["currentCorrectionRange"] as? [String: AnyObject],
let minValue = lastCorrection["minValue"] as? Double,
let maxValue = lastCorrection["maxValue"] as? Double {

let lastCorrection = lastOverride["currentCorrectionRange"] as! [String: AnyObject]
if let multiplier = lastOverride["multiplier"] as? Double {
currentOverride = multiplier
oText += String(format: "%.0f%%", (multiplier * 100))
}
else
{
} else {
oText += "100%"
}
oText += " ("
let minValue = lastCorrection["minValue"] as! Double
let maxValue = lastCorrection["maxValue"] as! Double
oText += bgUnits.toDisplayUnits(String(minValue)) + "-" + bgUnits.toDisplayUnits(String(maxValue)) + ")"

tableData[3].value = oText
oText += " ("
oText += Localizer.toDisplayUnits(String(minValue)) + "-" + Localizer.toDisplayUnits(String(maxValue)) + ")"
}

infoManager.updateInfoData(type: .override, value: oText)
} else {
infoManager.clearInfoData(type: .override)
}

infoTable.reloadData()


// Start the timer based on the timestamp
let now = dateTimeUtils.getNowTimeIntervalUTC()
let secondsAgo = now - latestLoopTime
Expand Down
58 changes: 45 additions & 13 deletions LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation
import UIKit
import Charts
import HealthKit

extension MainViewController {
func DeviceStatusLoop(formatter: ISO8601DateFormatter, lastLoopRecord: [String: AnyObject]) {
Expand All @@ -29,17 +30,44 @@ extension MainViewController {

}
}
if let iobdata = lastLoopRecord["iob"] as? [String:AnyObject] {
tableData[0].value = String(format:"%.2f", (iobdata["iob"] as! Double))
latestIOB = String(format:"%.2f", (iobdata["iob"] as! Double))

// ISF
let profileISF = profileManager.currentISF()
if let profileISF = profileISF {
infoManager.updateInfoData(type: .isf, value: profileISF)
}

// Carb Ratio (CR)
let profileCR = profileManager.currentCarbRatio()
if let profileCR = profileCR {
infoManager.updateInfoData(type: .carbRatio, value: profileCR)
}
if let cobdata = lastLoopRecord["cob"] as? [String:AnyObject] {
tableData[1].value = String(format:"%.0f", cobdata["cob"] as! Double)
latestCOB = String(format:"%.0f", cobdata["cob"] as! Double)

// Target
let profileTargetLow = profileManager.currentTargetLow()
let profileTargetHigh = profileManager.currentTargetHigh()

if let profileTargetLow = profileTargetLow, let profileTargetHigh = profileTargetHigh, profileTargetLow != profileTargetHigh {
infoManager.updateInfoData(type: .target, firstValue: profileTargetLow, secondValue: profileTargetHigh, separator: .dash)
} else if let profileTargetLow = profileTargetLow {
infoManager.updateInfoData(type: .target, value: profileTargetLow)
}

// IOB
if let insulinMetric = InsulinMetric(from: lastLoopRecord["iob"], key: "iob") {
infoManager.updateInfoData(type: .iob, value: insulinMetric)
latestIOB = insulinMetric
}

// COB
if let cobMetric = CarbMetric(from: lastLoopRecord["cob"], key: "cob") {
infoManager.updateInfoData(type: .cob, value: cobMetric)
latestCOB = cobMetric
}

if let predictdata = lastLoopRecord["predicted"] as? [String:AnyObject] {
let prediction = predictdata["values"] as! [Double]
PredictionLabel.text = bgUnits.toDisplayUnits(String(Int(prediction.last!)))
PredictionLabel.text = Localizer.toDisplayUnits(String(Int(prediction.last!)))
PredictionLabel.textColor = UIColor.systemPurple
if UserDefaultsRepository.downloadPrediction.value && latestLoopTime < lastLoopTime {
predictionData.removeAll()
Expand All @@ -59,19 +87,23 @@ extension MainViewController {
i += 1
}

let predMin = prediction.min()
let predMax = prediction.max()
tableData[9].value = bgUnits.toDisplayUnits(String(predMin!)) + "/" + bgUnits.toDisplayUnits(String(predMax!))

if let predMin = prediction.min(), let predMax = prediction.max() {
let formattedMin = Localizer.toDisplayUnits(String(predMin))
let formattedMax = Localizer.toDisplayUnits(String(predMax))
let value = "\(formattedMin)/\(formattedMax)"
infoManager.updateInfoData(type: .minMax, value: value)
}

updatePredictionGraph()
}
} else {
predictionData.removeAll()
tableData[9].value = ""
infoManager.clearInfoData(type: .minMax)
updatePredictionGraph()
}
if let recBolus = lastLoopRecord["recommendedBolus"] as? Double {
tableData[8].value = String(format:"%.2fU", recBolus)
let formattedRecBolus = String(format: "%.2fU", recBolus)
infoManager.updateInfoData(type: .recBolus, value: formattedRecBolus)
UserDefaultsRepository.deviceRecBolus.value = recBolus
}
if let loopStatus = lastLoopRecord["recommendedTempBasal"] as? [String:AnyObject] {
Expand Down
Loading