Skip to content

Commit

Permalink
premeal
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorkert committed Mar 7, 2023
1 parent 7878eae commit 90105ed
Show file tree
Hide file tree
Showing 4 changed files with 468 additions and 75 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ Loop 3 may upload duplicate svg entries, which can cause issues with LoopFollow'
 
## Carbs Today
This patch adds a new item to the 'Information Table' called 'Carbs Today.' This feature provides a sum of all registered carbs since midnight to help you keep track of your child's carb intake for the day. However, please note that this feature may not be useful if you are using fake carbs.
## PreMeal
The graph displays the PreMeal period as an orange band located below the green override band.
1 change: 1 addition & 0 deletions lf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ if [ $(basename $PWD) = "LoopFollow" ] && [ -d "LoopFollow" ]; then
add_patch "Protein line -90 minutes" "proteinLine" ""
add_patch "Duplicate blood glucose entries" "removeSVGDuplicates" ""
add_patch "Carbs Today" "carbstoday" ""
add_patch "PreMeal" "lf_temporary_target" ""

echo "Downloading patches, please wait..."
cd $mytmpdir
Expand Down
205 changes: 130 additions & 75 deletions lf_temporary_target.patch
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
From 4212aa0d69c8b7d65b1143ab1e9a0faa8306ab9b Mon Sep 17 00:00:00 2001
From 1f86bc64cb7bd77dc2dee0ca57d950550daa254e Mon Sep 17 00:00:00 2001
From: bjorkert <[email protected]>
Date: Tue, 28 Feb 2023 19:34:36 +0100
Date: Tue, 7 Mar 2023 17:22:37 +0100
Subject: [PATCH] =?UTF-8?q?=E2=80=9Clf=5Ftemporary=5Ftarget=E2=80=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
LoopFollow/Controllers/Graphs.swift | 57 ++++++++++++++-
LoopFollow/Controllers/NightScout.swift | 73 ++++++++++++++++++-
LoopFollow/Controllers/Graphs.swift | 86 +++++++++++++++++++
LoopFollow/Controllers/NightScout.swift | 85 ++++++++++++++++++
.../ViewControllers/MainViewController.swift | 1 +
LoopFollow/helpers/Chart.swift | 7 ++
LoopFollow/helpers/DataStructs.swift | 8 ++
5 files changed, 143 insertions(+), 3 deletions(-)
5 files changed, 187 insertions(+)

diff --git a/LoopFollow/Controllers/Graphs.swift b/LoopFollow/Controllers/Graphs.swift
index 485dd71..087d0ee 100644
index 485dd71..cdb8897 100644
--- a/LoopFollow/Controllers/Graphs.swift
+++ b/LoopFollow/Controllers/Graphs.swift
@@ -267,6 +267,20 @@ extension MainViewController {
lineNote.valueFormatter = ChartYDataValueFormatter()
lineNote.drawValuesEnabled = false

+ // Notes
+ // Temporary Target
+ var chartEntryTemporaryTarget = [ChartDataEntry]()
+ let lineTemporaryTarget = LineChartDataSet(entries:chartEntryTemporaryTarget, label: "")
+ lineTemporaryTarget.setDrawHighlightIndicators(false)
Expand All @@ -35,36 +35,62 @@ index 485dd71..087d0ee 100644
+ lineTemporaryTarget.axisDependency = YAxis.AxisDependency.right
+ lineTemporaryTarget.highlightEnabled = true
+ lineTemporaryTarget.drawValuesEnabled = false
+
+
// Setup the chart data of all lines
let data = LineChartData()

@@ -282,7 +296,8 @@ extension MainViewController {
@@ -282,6 +296,7 @@ extension MainViewController {
data.append(lineResume) // Dataset 9
data.append(lineSensor) // Dataset 10
data.append(lineNote) // Dataset 11
-
+ data.append(lineTemporaryTarget) // Dataset 12
+
data.setValueFont(UIFont.systemFont(ofSize: 12))

// Add marker popups for bolus and carbs
@@ -1240,6 +1255,46 @@ extension MainViewController {
@@ -1142,6 +1157,20 @@ extension MainViewController {
lineNote.valueFormatter = ChartYDataValueFormatter()
lineNote.drawValuesEnabled = false

+ // Temporary Target
+ var chartEntryTemporaryTarget = [ChartDataEntry]()
+ let lineTemporaryTarget = LineChartDataSet(entries:chartEntryTemporaryTarget, label: "")
+ lineTemporaryTarget.setDrawHighlightIndicators(false)
+ lineTemporaryTarget.lineWidth = 0
+ lineTemporaryTarget.drawFilledEnabled = true
+ lineTemporaryTarget.fillFormatter = TemporaryTargetFillFormatter()
+ lineTemporaryTarget.fillColor = NSUIColor.systemOrange
+ lineTemporaryTarget.fillAlpha = 0.6
+ lineTemporaryTarget.drawCirclesEnabled = false
+ lineTemporaryTarget.axisDependency = YAxis.AxisDependency.right
+ lineTemporaryTarget.highlightEnabled = true
+ lineTemporaryTarget.drawValuesEnabled = false
+
// Setup the chart data of all lines
let data = LineChartData()
data.append(lineBG) // Dataset 0
@@ -1156,6 +1185,7 @@ extension MainViewController {
data.append(lineResume) // Dataset 9
data.append(lineSensor) // Dataset 10
data.append(lineNote) // Dataset 11
+ data.append(lineTemporaryTarget) // Dataset 12

BGChartFull.highlightPerDragEnabled = true
BGChartFull.leftAxis.enabled = false
@@ -1240,6 +1270,62 @@ extension MainViewController {
BGChartFull.notifyDataSetChanged()
}
}
+
+
+ func updateTemporaryTargetGraph() {
+ var dataIndex = 12
+ var yTop: Double = Double(topBG - 25)
+ var yBottom: Double = Double(topBG - 45)
+ var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
+// var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
+ let dataIndex = 12
+ let yTop: Double = Double(topBG - 25)
+ let yBottom: Double = Double(topBG - 45)
+ let chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
+ let smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
+ chart.clear()
+// smallChart.clear()
+ smallChart.clear()
+ let thisData = temporaryTargetGraphData
+
+ var colors = [NSUIColor]()
+
+ for i in 0..<thisData.count{
+ let thisItem = thisData[i]
+ var labelText = thisItem.reason + "\r\n"
Expand All @@ -76,40 +102,55 @@ index 485dd71..087d0ee 100644
+ // Shift dots 30 seconds to create an empty 0 space between consecutive temps
+ let preStartDot = ChartDataEntry(x: Double(thisItem.date), y: yBottom, data: labelText)
+ BGChart.data?.dataSets[dataIndex].addEntry(preStartDot)
+ if UserDefaultsRepository.smallGraphTreatments.value {
+ BGChartFull.data?.dataSets[dataIndex].addEntry(preStartDot)
+ }
+
+ let startDot = ChartDataEntry(x: Double(thisItem.date + 1), y: yTop, data: labelText)
+ BGChart.data?.dataSets[dataIndex].addEntry(startDot)
+ if UserDefaultsRepository.smallGraphTreatments.value {
+ BGChartFull.data?.dataSets[dataIndex].addEntry(startDot)
+ }
+
+ // End Dot
+ let endDot = ChartDataEntry(x: Double(thisItem.endDate - 2), y: yTop, data: labelText)
+ BGChart.data?.dataSets[dataIndex].addEntry(endDot)
+ if UserDefaultsRepository.smallGraphTreatments.value {
+ BGChartFull.data?.dataSets[dataIndex].addEntry(endDot)
+ }
+
+ // Post end dot
+ let postEndDot = ChartDataEntry(x: Double(thisItem.endDate - 1), y: yBottom, data: labelText)
+
+ BGChart.data?.dataSets[dataIndex].addEntry(postEndDot)
+ if UserDefaultsRepository.smallGraphTreatments.value {
+ BGChartFull.data?.dataSets[dataIndex].addEntry(postEndDot)
+ }
+ }
+
+
+ BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
+ BGChart.data?.notifyDataChanged()
+ BGChart.notifyDataSetChanged()
+ if UserDefaultsRepository.smallGraphTreatments.value {
+ BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
+ BGChartFull.data?.notifyDataChanged()
+ BGChartFull.notifyDataSetChanged()
+ }
+ }

func formatPillText(line1: String, time: TimeInterval) -> String {
let dateFormatter = DateFormatter()
diff --git a/LoopFollow/Controllers/NightScout.swift b/LoopFollow/Controllers/NightScout.swift
index e846bfa..b2288ea 100644
index e846bfa..de8c36b 100644
--- a/LoopFollow/Controllers/NightScout.swift
+++ b/LoopFollow/Controllers/NightScout.swift
@@ -995,7 +995,8 @@ extension MainViewController {
@@ -995,6 +995,7 @@ extension MainViewController {
var resumePump: [[String:AnyObject]] = []
var pumpSiteChange: [[String:AnyObject]] = []
var cgmSensorStart: [[String:AnyObject]] = []
-
+ var temporaryTarget: [[String:AnyObject]] = []
+
for i in 0..<entries.count {
let entry = entries[i] as [String : AnyObject]?
switch entry?["eventType"] as! String {
@@ -1023,6 +1024,8 @@ extension MainViewController {
pumpSiteChange.append(entry!)
case "Sensor Start":
Expand All @@ -133,12 +174,10 @@ index e846bfa..b2288ea 100644
if note.count > 0 {
processNotes(entries: note)
} else {
@@ -1147,7 +1157,13 @@ extension MainViewController {
noteGraphData.removeAll()
@@ -1148,6 +1158,12 @@ extension MainViewController {
updateNotes()
}
-
+

+ func clearOldTemporaryTarget()
+ {
+ noteGraphData.removeAll()
Expand All @@ -148,58 +187,74 @@ index e846bfa..b2288ea 100644
// NS Temp Basal Response Processor
func processNSBasals(entries: [[String:AnyObject]]) {
self.clearLastInfoData(index: 2)
@@ -1749,4 +1765,57 @@ extension MainViewController {
@@ -1749,4 +1765,73 @@ extension MainViewController {
}

}
+
+
+ // Temporary Target Processor
+ func processTemporaryTarget(entries: [[String:AnyObject]]) {
+ if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: Temporary Target") }
+ temporaryTargetGraphData.removeAll()
+
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
+ dateFormatter.locale = Locale(identifier: "en_US")
+ dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
+
+ let graphHours = 24 * UserDefaultsRepository.downloadDays.value
+ var date: String
+ var strippedZone: String
+ for i in 0..<entries.count {
+ let currentEntry = entries[entries.count - 1 - i] as [String : AnyObject]?
+ var date: String
+ if currentEntry?["timestamp"] != nil {
+ date = currentEntry?["timestamp"] as! String
+ } else if currentEntry?["created_at"] != nil {
+ date = currentEntry?["created_at"] as! String
+ } else {
+ return
+ }
+ // Fix for FreeAPS milliseconds in timestamp
+ var strippedZone = String(date.dropLast())
+ strippedZone = strippedZone.components(separatedBy: ".")[0]
+
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
+ dateFormatter.locale = Locale(identifier: "en_US")
+ dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
+ let dateString = dateFormatter.date(from: strippedZone)
+ var dateTimeStamp = dateString!.timeIntervalSince1970
+ let graphHours = 24 * UserDefaultsRepository.downloadDays.value
+ if dateTimeStamp < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) {
+ dateTimeStamp = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
+ }
+
+ var duration: Double = 5.0
+ if let durationType = currentEntry?["durationType"] as? String {
+ duration = dateTimeUtils.getNowTimeIntervalUTC() - dateTimeStamp + (60 * 60)
+ } else {
+ duration = (currentEntry?["duration"] as? Double)!
+ duration = duration * 60
+ if currentEntry?["duration"] as! Int > 0 {
+ var duration: Double = 5.0
+ if currentEntry?["created_at"] != nil {
+ date = currentEntry?["created_at"] as! String
+ } else {
+ return
+ }
+ // Fix for FreeAPS milliseconds in timestamp
+ strippedZone = String(date.dropLast())
+ strippedZone = strippedZone.components(separatedBy: ".")[0]
+
+ let dateString = dateFormatter.date(from: strippedZone)
+ var dateTimeStamp = dateString!.timeIntervalSince1970
+ if dateTimeStamp < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) {
+ dateTimeStamp = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
+ }
+
+ if(entries.count - 2 - i >= 0)
+ {
+ let nextEntry = entries[entries.count - 2 - i] as [String : AnyObject]?
+ date = nextEntry?["created_at"] as! String
+ strippedZone = String(date.dropLast())
+ strippedZone = strippedZone.components(separatedBy: ".")[0]
+
+ let endDateString = dateFormatter.date(from: strippedZone)
+ var endDateTimeStamp = endDateString!.timeIntervalSince1970
+ if endDateTimeStamp < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) {
+ endDateTimeStamp = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
+ }
+ duration = endDateTimeStamp - dateTimeStamp
+ }
+ else
+ {
+ duration = (currentEntry?["duration"] as? Double)!
+ duration = duration * 60
+ }
+
+ // Skip temporary targets that aren't 5 minutes long. This prevents overlapping that causes bars to not display.
+ if duration < 300 { continue }
+
+ guard let enteredBy = currentEntry?["enteredBy"] as? String else { continue }
+ guard let reason = currentEntry?["reason"] as? String else { continue }
+
+ let endDate = dateTimeStamp + (duration)
+
+ let dot = DataStructs.temporaryTargetStruct(date: dateTimeStamp, endDate: endDate, duration: duration, enteredBy: enteredBy, reason: reason)
+ temporaryTargetGraphData.append(dot)
+ }
+
+ // Skip temporary targets that aren't 5 minutes long. This prevents overlapping that causes bars to not display.
+ if duration < 300 { continue }
+
+ guard let enteredBy = currentEntry?["enteredBy"] as? String else { continue }
+ guard let reason = currentEntry?["reason"] as? String else { continue }
+
+ let endDate = dateTimeStamp + (duration)
+
+ let dot = DataStructs.temporaryTargetStruct(date: dateTimeStamp, endDate: endDate, duration: duration, enteredBy: enteredBy, reason: reason)
+ temporaryTargetGraphData.append(dot)
+ }
+ if UserDefaultsRepository.graphOtherTreatments.value {
+ updateTemporaryTargetGraph()
Expand Down
Loading

0 comments on commit 90105ed

Please sign in to comment.