Skip to content

Commit

Permalink
Override and temp target functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorkert committed Oct 12, 2024
1 parent 9e41558 commit 4cd6e12
Show file tree
Hide file tree
Showing 16 changed files with 616 additions and 36 deletions.
4 changes: 4 additions & 0 deletions LoopFollow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
DD98F54424BCEFEE0007425A /* ShareClientExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD98F54324BCEFEE0007425A /* ShareClientExtension.swift */; };
DDB0AF522BB1A8BE00AFA48B /* BuildDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB0AF512BB1A8BE00AFA48B /* BuildDetails.swift */; };
DDB0AF552BB1B24A00AFA48B /* BuildDetails.plist in Resources */ = {isa = PBXBuildFile; fileRef = DDB0AF542BB1B24A00AFA48B /* BuildDetails.plist */; };
DDBE3ABD2CB5A961006B37DC /* OverrideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDBE3ABC2CB5A961006B37DC /* OverrideView.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 */; };
Expand Down Expand Up @@ -303,6 +304,7 @@
DDB0AF502BB1A84500AFA48B /* capture-build-details.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "capture-build-details.sh"; sourceTree = "<group>"; };
DDB0AF512BB1A8BE00AFA48B /* BuildDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildDetails.swift; sourceTree = "<group>"; };
DDB0AF542BB1B24A00AFA48B /* BuildDetails.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = BuildDetails.plist; sourceTree = "<group>"; };
DDBE3ABC2CB5A961006B37DC /* OverrideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideView.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>"; };
Expand Down Expand Up @@ -575,6 +577,7 @@
DD4878142C7B75230048F05C /* MealView.swift */,
DD4878162C7B75350048F05C /* BolusView.swift */,
DDFD5C522CB167DA00D3FD68 /* TRCCommandType.swift */,
DDBE3ABC2CB5A961006B37DC /* OverrideView.swift */,
);
path = TRC;
sourceTree = "<group>";
Expand Down Expand Up @@ -1218,6 +1221,7 @@
DDFD5C532CB167DA00D3FD68 /* TRCCommandType.swift in Sources */,
DD16AF112C997B4600FB655A /* LoadingButtonView.swift in Sources */,
FC16A97B249966A3003D6245 /* AlarmSound.swift in Sources */,
DDBE3ABD2CB5A961006B37DC /* OverrideView.swift in Sources */,
DDB0AF522BB1A8BE00AFA48B /* BuildDetails.swift in Sources */,
DD0C0C622C4175FD00DBADDF /* NSProfile.swift in Sources */,
DDE69ED22C7256260013EAEC /* RemoteType.swift in Sources */,
Expand Down
253 changes: 248 additions & 5 deletions LoopFollow/Controllers/Graphs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,52 @@ import UIKit

import Charts

enum GraphDataIndex: Int {
case bg = 0
case prediction = 1
case basal = 2
case bolus = 3
case carbs = 4
case basalScheduled = 5
case override = 6
case bgCheck = 7
case suspend = 8
case resumePump = 9
case sensorStart = 10
case note = 11
case ztPrediction = 12
case iobPrediction = 13
case cobPrediction = 14
case uamPrediction = 15
case smb = 16
case tempTarget = 17
}

extension GraphDataIndex {
var description: String {
switch self {
case .bg: return "BG"
case .prediction: return "Prediction"
case .basal: return "Basal"
case .bolus: return "Bolus"
case .carbs: return "Carbs"
case .basalScheduled: return "Basal Scheduled"
case .override: return "Override"
case .bgCheck: return "BG Check"
case .suspend: return "Suspend"
case .resumePump: return "Resume Pump"
case .sensorStart: return "Sensor Start"
case .note: return "Note"
case .ztPrediction: return "ZT Prediction"
case .iobPrediction: return "IOB Prediction"
case .cobPrediction: return "COB Prediction"
case .uamPrediction: return "UAM Prediction"
case .smb: return "SMB"
case .tempTarget: return "Temp Target"
}
}
}

class TriangleRenderer: LineChartRenderer {
let smbDataSetIndex: Int

Expand Down Expand Up @@ -50,6 +96,87 @@ class TriangleRenderer: LineChartRenderer {
}
}

class TempTargetChartDataEntry: ChartDataEntry {
var xStart: Double = 0.0
var xEnd: Double = 0.0
var yTop: Double = 0.0
var yBottom: Double = 0.0

required init() {
super.init()
}

init(xStart: Double, xEnd: Double, yTop: Double, yBottom: Double, data: Any?) {
self.xStart = xStart
self.xEnd = xEnd
self.yTop = yTop
self.yBottom = yBottom

super.init(x: xStart, y: yTop)
self.data = data
}

override func copy(with zone: NSZone? = nil) -> Any {
let copy = TempTargetChartDataEntry(
xStart: xStart,
xEnd: xEnd,
yTop: yTop,
yBottom: yBottom,
data: data
)
return copy
}
}

class TempTargetRenderer: LineChartRenderer {
let tempTargetDataSetIndex: Int

init(dataProvider: LineChartDataProvider?, animator: Animator?, viewPortHandler: ViewPortHandler?, tempTargetDataSetIndex: Int) {
self.tempTargetDataSetIndex = tempTargetDataSetIndex
super.init(dataProvider: dataProvider!, animator: animator!, viewPortHandler: viewPortHandler!)
}

override func drawExtras(context: CGContext) {
super.drawExtras(context: context)

guard let dataProvider = dataProvider else { return }

if dataProvider.lineData?.dataSets.count ?? 0 > tempTargetDataSetIndex,
let lineDataSet = dataProvider.lineData?.dataSets[tempTargetDataSetIndex] as? LineChartDataSet {

let trans = dataProvider.getTransformer(forAxis: lineDataSet.axisDependency)
let phaseY = animator.phaseY

for i in 0 ..< lineDataSet.entryCount {
guard let entry = lineDataSet.entryForIndex(i) as? TempTargetChartDataEntry else { continue }

let xStart = entry.xStart
let xEnd = entry.xEnd
let yTop = entry.yTop * phaseY
let yBottom = entry.yBottom * phaseY

let leftTop = trans.pixelForValues(x: xStart, y: yTop)
let rightBottom = trans.pixelForValues(x: xEnd, y: yBottom)

var rect = CGRect(x: leftTop.x, y: leftTop.y, width: rightBottom.x - leftTop.x, height: rightBottom.y - leftTop.y)
if rect.width < 0 {
rect.origin.x += rect.width
rect.size.width = abs(rect.width)
}
if rect.height < 0 {
rect.origin.y += rect.height
rect.size.height = abs(rect.height)
}

context.saveGState()
context.setFillColor(NSUIColor.systemPurple.withAlphaComponent(0.5).cgColor)
context.fill(rect)
context.restoreGState()
}
}
}
}

let ScaleXMax:Float = 150.0
extension MainViewController {

Expand Down Expand Up @@ -414,7 +541,20 @@ extension MainViewController {
lineSmb.drawValuesEnabled = false
lineSmb.highlightEnabled = true
}


// TempTarget graph data
let chartTempTargetEntry = [ChartDataEntry]()
let lineTempTarget = LineChartDataSet(entries:chartTempTargetEntry, label: "")
lineTempTarget.setDrawHighlightIndicators(false)
lineTempTarget.lineWidth = 0
lineTempTarget.drawFilledEnabled = false
lineTempTarget.fillColor = NSUIColor.systemPurple
lineTempTarget.fillAlpha = 0.6
lineTempTarget.drawCirclesEnabled = false
lineTempTarget.axisDependency = YAxis.AxisDependency.right
lineTempTarget.highlightEnabled = true
lineTempTarget.drawValuesEnabled = false

// Setup the chart data of all lines
let data = LineChartData()

Expand All @@ -435,6 +575,7 @@ extension MainViewController {
data.append(COBlinePrediction) // Dataset 14
data.append(UAMlinePrediction) // Dataset 15
data.append(lineSmb) // Dataset 16
data.append(lineTempTarget)

data.setValueFont(UIFont.systemFont(ofSize: 12))

Expand Down Expand Up @@ -1414,7 +1555,20 @@ extension MainViewController {
lineSmb.drawFilledEnabled = false
lineSmb.drawValuesEnabled = false
lineSmb.highlightEnabled = false


// Temp Target graph data
let chartTempTargetEntry = [ChartDataEntry]()
let lineTempTarget = LineChartDataSet(entries:chartTempTargetEntry, label: "")
lineTempTarget.setDrawHighlightIndicators(false)
lineTempTarget.lineWidth = 0
lineTempTarget.drawFilledEnabled = false
lineTempTarget.fillColor = NSUIColor.systemPurple
lineTempTarget.fillAlpha = 0.6
lineTempTarget.drawCirclesEnabled = false
lineTempTarget.axisDependency = YAxis.AxisDependency.right
lineTempTarget.highlightEnabled = true
lineTempTarget.drawValuesEnabled = false

// Setup the chart data of all lines
let data = LineChartData()
data.append(lineBG) // Dataset 0
Expand All @@ -1434,6 +1588,7 @@ extension MainViewController {
data.append(COBlinePrediction) // Dataset 14
data.append(UAMlinePrediction) // Dataset 15
data.append(lineSmb) // Dataset 16
data.append(lineTempTarget)

BGChartFull.highlightPerDragEnabled = true
BGChartFull.leftAxis.enabled = false
Expand All @@ -1452,8 +1607,6 @@ extension MainViewController {
BGChartFull.scaleXEnabled = false
BGChartFull.drawGridBackgroundEnabled = false
BGChartFull.data = data


}

func updateOverrideGraph() {
Expand Down Expand Up @@ -1518,7 +1671,97 @@ extension MainViewController {
BGChartFull.notifyDataSetChanged()
}
}


func getChartDataSets(for index: GraphDataIndex) -> (chart: LineChartDataSet?, smallChart: LineChartDataSet?) {
guard let chart = BGChart.lineData,
index.rawValue < chart.dataSets.count,
let smallChartData = BGChartFull.lineData,
index.rawValue < smallChartData.dataSets.count else {
print("Warning: Invalid GraphDataIndex \(index.description) or lineData is nil.")
return (nil, nil)
}

let chartDataSet = chart.dataSets[index.rawValue] as? LineChartDataSet
let smallChartDataSet = smallChartData.dataSets[index.rawValue] as? LineChartDataSet

return (chartDataSet, smallChartDataSet)
}

func addEntryToCharts(entry: ChartDataEntry, chart: LineChartDataSet, smallChart: LineChartDataSet?) {
chart.addEntry(entry)
if UserDefaultsRepository.smallGraphTreatments.value, let smallChart = smallChart {
smallChart.addEntry(entry)
}
}

func updateTempTargetGraph() {
let dataIndex = GraphDataIndex.tempTarget.rawValue
guard let chartData = BGChart.lineData,
chartData.dataSets.count > dataIndex,
let mainChartDataSet = chartData.dataSets[dataIndex] as? LineChartDataSet else {
print("Error: Could not retrieve temp target datasets.")
return
}

mainChartDataSet.clear()

var smallChartDataSet: LineChartDataSet?
if UserDefaultsRepository.smallGraphTreatments.value,
let smallChartData = BGChartFull.lineData,
smallChartData.dataSets.count > dataIndex,
let smallDataSet = smallChartData.dataSets[dataIndex] as? LineChartDataSet {
smallChartDataSet = smallDataSet
smallChartDataSet?.clear()
}

let thisData = tempTargetGraphData

for tempTarget in thisData {
let xStart = tempTarget.date
let xEnd = tempTarget.endDate
let yCenter = Double(tempTarget.correctionRange[0])
let yTop = yCenter + 5.0
let yBottom = yCenter - 5.0

let entry = TempTargetChartDataEntry(
xStart: xStart,
xEnd: xEnd,
yTop: yTop,
yBottom: yBottom,
data: nil
)
mainChartDataSet.addEntry(entry)

if let smallDataSet = smallChartDataSet {
smallDataSet.addEntry(entry)
}
}

let tempTargetRenderer = TempTargetRenderer(
dataProvider: BGChart,
animator: BGChart.chartAnimator,
viewPortHandler: BGChart.viewPortHandler,
tempTargetDataSetIndex: dataIndex
)
BGChart.renderer = tempTargetRenderer

BGChart.data?.notifyDataChanged()
BGChart.notifyDataSetChanged()

if let smallDataSet = smallChartDataSet {
let tempTargetRendererSmall = TempTargetRenderer(
dataProvider: BGChartFull,
animator: BGChartFull.chartAnimator,
viewPortHandler: BGChartFull.viewPortHandler,
tempTargetDataSetIndex: dataIndex
)
BGChartFull.renderer = tempTargetRendererSmall

BGChartFull.data?.notifyDataChanged()
BGChartFull.notifyDataSetChanged()
}
}

func wrapText(_ text: String, maxLineLength: Int) -> String {
var lines: [String] = []
var currentLine = ""
Expand Down
6 changes: 6 additions & 0 deletions LoopFollow/Controllers/NightScout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ extension MainViewController {
updateOverrideGraph()
}

func clearOldTempTarget()
{
tempTargetGraphData.removeAll()
updateTempTargetGraph()
}

func clearOldSuspend()
{
suspendGraphData.removeAll()
Expand Down
19 changes: 19 additions & 0 deletions LoopFollow/Controllers/Nightscout/NSProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,23 @@ struct NSProfile: Decodable {
let bundleIdentifier: String?
let isAPNSProduction: Bool?
let deviceToken: String?

struct TrioOverrideEntry: Decodable {
let name: String
let duration: Double?
let percentage: Double?
let target: Double?
}

let trioOverrides: [TrioOverrideEntry]?

enum CodingKeys: String, CodingKey {
case store
case defaultProfile
case units
case bundleIdentifier
case isAPNSProduction
case deviceToken
case trioOverrides = "overrides"
}
}
Loading

0 comments on commit 4cd6e12

Please sign in to comment.