Skip to content
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
12 changes: 12 additions & 0 deletions LoopFollow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
3F1335F351590E573D8E6962 /* Pods_LoopFollow.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D55B42A22051DAD69E89D0 /* Pods_LoopFollow.framework */; };
DD98F54424BCEFEE0007425A /* ShareClientExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD98F54324BCEFEE0007425A /* ShareClientExtension.swift */; };
FC16A97A24996673003D6245 /* NightScout.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A97924996673003D6245 /* NightScout.swift */; };
FC16A97B249966A3003D6245 /* AlarmSound.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC7CE589248ABEA3001F83B8 /* AlarmSound.swift */; };
FC16A97D24996747003D6245 /* Alarms.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A97C24996747003D6245 /* Alarms.swift */; };
Expand Down Expand Up @@ -162,6 +163,7 @@
/* Begin PBXFileReference section */
059B0FA59AABFE72FE13DDDA /* Pods-LoopFollow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LoopFollow.release.xcconfig"; path = "Target Support Files/Pods-LoopFollow/Pods-LoopFollow.release.xcconfig"; sourceTree = "<group>"; };
A7D55B42A22051DAD69E89D0 /* Pods_LoopFollow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LoopFollow.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DD98F54324BCEFEE0007425A /* ShareClientExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareClientExtension.swift; sourceTree = "<group>"; };
ECA3EFB4037410B4973BB632 /* Pods-LoopFollow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LoopFollow.debug.xcconfig"; path = "Target Support Files/Pods-LoopFollow/Pods-LoopFollow.debug.xcconfig"; sourceTree = "<group>"; };
FC16A97924996673003D6245 /* NightScout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightScout.swift; sourceTree = "<group>"; };
FC16A97C24996747003D6245 /* Alarms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alarms.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -350,6 +352,14 @@
path = Pods;
sourceTree = "<group>";
};
DD98F54224BCEF190007425A /* Extensions */ = {
isa = PBXGroup;
children = (
DD98F54324BCEFEE0007425A /* ShareClientExtension.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
FC16A97624995FEE003D6245 /* Application */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -513,6 +523,7 @@
FC8DEEE62485D1ED0075863F /* Info.plist */,
FC7CE59A248D334B001F83B8 /* Resources */,
FCC68871248A736700A0279D /* ViewControllers */,
DD98F54224BCEF190007425A /* Extensions */,
FC16A9782499657E003D6245 /* Controllers */,
FCC688542489367300A0279D /* helpers */,
FCC68872248A748A00A0279D /* Models */,
Expand Down Expand Up @@ -841,6 +852,7 @@
FCC0FAC224922A22003E610E /* DictionaryKeyPath.swift in Sources */,
FC9788182485969B00A7906C /* AppDelegate.swift in Sources */,
FCC6886B24898FD800A0279D /* ObservationToken.swift in Sources */,
DD98F54424BCEFEE0007425A /* ShareClientExtension.swift in Sources */,
FCC6886D2489909D00A0279D /* AnyConvertible.swift in Sources */,
FC97881A2485969B00A7906C /* SceneDelegate.swift in Sources */,
FCD49B6C24AA536E007879DC /* DebugViewController.swift in Sources */,
Expand Down
51 changes: 33 additions & 18 deletions LoopFollow/Application/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions LoopFollow/Controllers/Stats.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class StatsData {
var totalGlucose: Int
var avgBG: Float
var a1C: Float
var stdDev: Float
var pie: [DataStructs.pieData]

init(bgData: [DataStructs.sgvData]) {
Expand Down Expand Up @@ -54,8 +55,6 @@ class StatsData {
DataStructs.pieData(name: "range", value: Double(percentRange)),
DataStructs.pieData(name: "high", value: Double(percentHigh))]



// Set Average
avgBG = Float(totalGlucose / bgData.count)

Expand All @@ -67,6 +66,13 @@ class StatsData {
// https://github.com/nightscout/nightguard/pull/72
// a1C = (((46.7 + Float(avgBG)) / 28.7) - 2.152) / 0.09148
}

// compute std dev (sigma)
var partialSum: Float = 0;
for i in 0..<bgData.count {
partialSum += (Float(bgData[i].sgv) - avgBG) * ( Float(bgData[i].sgv) - avgBG)
}
stdDev = sqrt(partialSum / Float(bgData.count))
}

}
3 changes: 2 additions & 1 deletion LoopFollow/Controllers/StatsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ extension MainViewController {
func updateStats()
{
if bgData.count > 0 {
var stats = StatsData(bgData: bgData)
let stats = StatsData(bgData: bgData)

statsLowPercent.text = String(format:"%.1f%", stats.percentLow) + "%"
statsInRangePercent.text = String(format:"%.1f%", stats.percentRange) + "%"
statsHighPercent.text = String(format:"%.1f%", stats.percentHigh) + "%"
statsAvgBG.text = bgUnits.toDisplayUnits(String(format:"%.0f%", stats.avgBG))
statsEstA1C.text = String(format:"%.1f%", stats.a1C)
statsStdDev.text = String(format:"%.2f%", stats.stdDev)

createStatsPie(pieData: stats.pie)
}
Expand Down
58 changes: 58 additions & 0 deletions LoopFollow/Extensions/ShareClientExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// ShareClientExtension.swift
// LoopFollow
//
// Created by Jose Paredes on 7/13/20.
// Copyright © 2020 Jon Fawcett. All rights reserved.
//

import Foundation
import ShareClient

public struct ShareGlucoseData: Codable {
var sgv: Int
var date: TimeInterval
var direction: String?
}

private var TrendTable: [String] = [
"NONE", // 0
"DoubleUp", // 1
"SingleUp", // 2
"FourtyFiveUp", // 3
"Flat", // 4
"FourtyFiveDown", // 5
"SingleDown", // 6
"DoubleDown" // 7
]

// TODO: probably better to make this an inherited class rather than an extension
extension ShareClient {

public func fetchData(_ entries: Int, callback: @escaping (ShareError?, [ShareGlucoseData]?) -> Void) {

self.fetchLast(entries) { (error, result) -> () in
guard error == nil || result != nil else {
return callback(error, nil)
}

// parse data to conanical form
var shareData = [ShareGlucoseData]()
for i in 0..<result!.count {

var trend = Int(result![i].trend)
if(trend < 0 || trend > TrendTable.count-1) {
trend = 0
}

let newShareData = ShareGlucoseData(
sgv: Int(result![i].glucose),
date: result![i].timestamp.timeIntervalSince1970,
direction: TrendTable[trend]
)
shareData.append(newShareData)
}
callback(nil,shareData)
}
}
}
40 changes: 33 additions & 7 deletions LoopFollow/ViewControllers/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import UIKit
import Charts
import EventKit
import ShareClient


class MainViewController: UIViewController, UITableViewDataSource, ChartViewDelegate, UNUserNotificationCenterDelegate {
Expand All @@ -30,6 +31,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
@IBOutlet weak var statsHighPercent: UILabel!
@IBOutlet weak var statsAvgBG: UILabel!
@IBOutlet weak var statsEstA1C: UILabel!
@IBOutlet weak var statsStdDev: UILabel!


// Data Table Struct
Expand Down Expand Up @@ -75,6 +77,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
var calTimer = Timer()

// Info Table Setup
// TODO: make this selectable
var tableData = [
infoData(name: "IOB", value: ""), //0
infoData(name: "COB", value: ""), //1
Expand Down Expand Up @@ -108,6 +111,10 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
var lastOverrideStartTime: TimeInterval = 0
var lastOverrideEndTime: TimeInterval = 0

// share
var bgDataShare: [ShareGlucoseData] = []
var dexShare: ShareClient?;

// calendar setup
let store = EKEventStore()

Expand All @@ -116,16 +123,21 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
override func viewDidLoad() {
super.viewDidLoad()

// TODO: look for username and password in the UserDefaultsRepo ?
// TODO: need non-us server ?
let shareUserName = UserDefaultsRepository.shareUserName.value
let sharePassword = UserDefaultsRepository.sharePassword.value
let shareServer = UserDefaultsRepository.shareServer.value == "US" ?KnownShareServers.US.rawValue : KnownShareServers.NON_US.rawValue
dexShare = ShareClient(username: shareUserName, password: sharePassword, shareServer: shareServer )

//print("Share: \(dexShare)")

// Start Log Timer if needed
if UserDefaultsRepository.debugLog.value {
guard let debug = self.tabBarController!.viewControllers?[5] as? debugViewController else { return }
debug.loadViewIfNeeded()
} else {
do {
try self.tabBarController?.viewControllers?.remove(at: 5)
} catch {

}
self.tabBarController?.viewControllers?.remove(at: 5)
}

BGChart.delegate = self
Expand Down Expand Up @@ -164,8 +176,15 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
// Load Data
if UserDefaultsRepository.url.value != "" && firstGraphLoad {
nightscoutLoader()

// TODO: move this to MainViewController extension ?
dexShare?.fetchData(262) { (err, result) -> () in

// TODO: add error checking
self.bgDataShare = result!
// print("\(self.bgDataShare)")
}
}

}

override func viewWillAppear(_ animated: Bool) {
Expand All @@ -174,7 +193,6 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele

}


// Info Table Functions
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
Expand Down Expand Up @@ -289,6 +307,14 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
// if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Main timer ended") }
updateMinAgo()
nightscoutLoader()

// TODO: move this to MainViewController extension ?
dexShare?.fetchData(262) { (err, result) -> () in

// TODO: add error checking
self.bgDataShare = result!
// print("\(self.bgDataShare)")
}
}

//update Min Ago Text. We need to call this separately because it updates between readings
Expand Down
34 changes: 34 additions & 0 deletions LoopFollow/ViewControllers/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ class SettingsViewController: FormViewController {
guard let value = row.value else { return }
UserDefaultsRepository.units.value = value
}
+++ Section("Dexcom Settings")
<<< TextRow(){ row in
row.title = "User Name"
row.value = UserDefaultsRepository.shareUserName.value
}.cellSetup { (cell, row) in
cell.textField.autocorrectionType = .no
}.onChange { row in
if row.value == nil {
UserDefaultsRepository.shareUserName.value = ""
}
guard let value = row.value else { return }
UserDefaultsRepository.shareUserName.value = value
}
<<< TextRow(){ row in
row.title = "Password"
row.value = UserDefaultsRepository.sharePassword.value
}.cellSetup { (cell, row) in
cell.textField.autocorrectionType = .no
cell.textField.isSecureTextEntry = true
}.onChange { row in
if row.value == nil {
UserDefaultsRepository.sharePassword.value = ""
}
guard let value = row.value else { return }
UserDefaultsRepository.sharePassword.value = value
}
<<< SegmentedRow<String>("shareServer") { row in
row.title = "Server"
row.options = ["US", "NON-US"]
row.value = UserDefaultsRepository.shareServer.value
}.onChange { row in
guard let value = row.value else { return }
UserDefaultsRepository.shareServer.value = value
}


buildGeneralSettings()
Expand Down
6 changes: 6 additions & 0 deletions LoopFollow/repository/UserDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import UIKit

class UserDefaultsRepository {


//Nightscout Settings
static let url = UserDefaultsValue<String>(key: "url", default: "")
static let token = UserDefaultsValue<String>(key: "token", default: "")
static let units = UserDefaultsValue<String>(key: "units", default: "mg/dL")

//Dexcom Share Settings
static let shareUserName = UserDefaultsValue<String>(key: "shareUserName", default: "")
static let sharePassword = UserDefaultsValue<String>(key: "sharePassword", default: "")
static let shareServer = UserDefaultsValue<String>(key: "shareServer", default: "US")

// Graph Settings
static let showDots = UserDefaultsValue<Bool>(key: "showDots", default: true)
static let showLines = UserDefaultsValue<Bool>(key: "showLines", default: true)
Expand Down
5 changes: 3 additions & 2 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ target 'LoopFollow' do

pod 'Charts'
pod 'Eureka'

end
pod 'ShareClient', :git => 'https://github.com/josep1972/dexcom-share-client-swift.git', :branch => 'dev'

end
15 changes: 14 additions & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,33 @@ PODS:
- Charts/Core (= 3.5.0)
- Charts/Core (3.5.0)
- Eureka (5.2.1)
- ShareClient (1.2)

DEPENDENCIES:
- Charts
- Eureka
- ShareClient (from `https://github.com/josep1972/dexcom-share-client-swift.git`, branch `dev`)

SPEC REPOS:
trunk:
- Charts
- Eureka

EXTERNAL SOURCES:
ShareClient:
:branch: dev
:git: https://github.com/josep1972/dexcom-share-client-swift.git

CHECKOUT OPTIONS:
ShareClient:
:commit: 815a1dbddd970a563e3b7fd22d88b23c164b026e
:git: https://github.com/josep1972/dexcom-share-client-swift.git

SPEC CHECKSUMS:
Charts: 40a08591df1f8ad5c223ddedfb1a06da92f24f7c
Eureka: c883105488e05bc65539f583246ecf9657cabbfe
ShareClient: 5937ff69b57c85c2004c915812f73cf7ae86549e

PODFILE CHECKSUM: 7665842405edac4f27ad84d4b66d6d57d5a4e5aa
PODFILE CHECKSUM: b5ee540f0ef2120e92d3b71909453c335d659552

COCOAPODS: 1.9.3
15 changes: 14 additions & 1 deletion Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading