MainChartHelper.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import CoreData
  2. import Foundation
  3. enum MainChartHelper {
  4. // Calculates the glucose value thats the nearest to parameter 'time'
  5. /// -Returns: A NSManagedObject of GlucoseStored
  6. /// it is thread safe as everything is executed on the main thread
  7. static func timeToNearestGlucose(glucoseValues: [GlucoseStored], time: TimeInterval) -> GlucoseStored? {
  8. guard !glucoseValues.isEmpty else {
  9. return nil
  10. }
  11. var low = 0
  12. var high = glucoseValues.count - 1
  13. var closestGlucose: GlucoseStored?
  14. // binary search to find next glucose
  15. while low <= high {
  16. let mid = low + (high - low) / 2
  17. let midTime = glucoseValues[mid].date?.timeIntervalSince1970 ?? 0
  18. if midTime == time {
  19. return glucoseValues[mid]
  20. } else if midTime < time {
  21. low = mid + 1
  22. } else {
  23. high = mid - 1
  24. }
  25. // update if necessary
  26. if closestGlucose == nil || abs(midTime - time) < abs(closestGlucose!.date?.timeIntervalSince1970 ?? 0 - time) {
  27. closestGlucose = glucoseValues[mid]
  28. }
  29. }
  30. return closestGlucose
  31. }
  32. enum Config {
  33. static let bolusSize: CGFloat = 5
  34. static let bolusScale: CGFloat = 1.8
  35. static let carbsSize: CGFloat = 5
  36. static let maxCarbSize: CGFloat = 30
  37. static let carbsScale: CGFloat = 0.3
  38. static let fpuSize: CGFloat = 10
  39. static let maxGlucose = 270
  40. static let minGlucose = 45
  41. }
  42. static var bolusFormatter: NumberFormatter {
  43. let formatter = NumberFormatter()
  44. formatter.numberStyle = .decimal
  45. formatter.minimumIntegerDigits = 0
  46. formatter.maximumFractionDigits = 2
  47. formatter.decimalSeparator = "."
  48. return formatter
  49. }
  50. static var carbsFormatter: NumberFormatter {
  51. let formatter = NumberFormatter()
  52. formatter.numberStyle = .decimal
  53. formatter.maximumFractionDigits = 0
  54. return formatter
  55. }
  56. static func bolusOffset(units: GlucoseUnits) -> Decimal {
  57. units == .mgdL ? 30 : 1.66
  58. }
  59. static func calculateDuration(objectID: NSManagedObjectID, context: NSManagedObjectContext) -> TimeInterval? {
  60. do {
  61. if let override = try context.existingObject(with: objectID) as? OverrideStored,
  62. let overrideDuration = override.duration as? Double, overrideDuration != 0
  63. {
  64. return TimeInterval(overrideDuration * 60) // return seconds
  65. }
  66. } catch {
  67. debugPrint(
  68. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to calculate Override Target with error: \(error.localizedDescription)"
  69. )
  70. }
  71. return nil
  72. }
  73. static func calculateTarget(objectID: NSManagedObjectID, context: NSManagedObjectContext) -> Decimal? {
  74. do {
  75. if let override = try context.existingObject(with: objectID) as? OverrideStored,
  76. let overrideTarget = override.target, overrideTarget != 0
  77. {
  78. return overrideTarget.decimalValue
  79. }
  80. } catch {
  81. debugPrint(
  82. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to calculate Override Target with error: \(error.localizedDescription)"
  83. )
  84. }
  85. return nil
  86. }
  87. }