MainChartHelper.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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
  35. static let carbsSize: CGFloat = 5
  36. static let carbsScale: CGFloat = 0.3
  37. static let fpuSize: CGFloat = 10
  38. static let maxGlucose = 270
  39. static let minGlucose = 45
  40. }
  41. static var bolusFormatter: NumberFormatter {
  42. let formatter = NumberFormatter()
  43. formatter.numberStyle = .decimal
  44. formatter.minimumIntegerDigits = 0
  45. formatter.maximumFractionDigits = 2
  46. formatter.decimalSeparator = "."
  47. return formatter
  48. }
  49. static var carbsFormatter: NumberFormatter {
  50. let formatter = NumberFormatter()
  51. formatter.numberStyle = .decimal
  52. formatter.maximumFractionDigits = 0
  53. return formatter
  54. }
  55. static func bolusOffset(units: GlucoseUnits) -> Decimal {
  56. units == .mgdL ? 30 : 1.66
  57. }
  58. static func calculateDuration(objectID: NSManagedObjectID, context: NSManagedObjectContext) -> TimeInterval? {
  59. do {
  60. if let override = try context.existingObject(with: objectID) as? OverrideStored,
  61. let overrideDuration = override.duration as? Double, overrideDuration != 0
  62. {
  63. return TimeInterval(overrideDuration * 60) // return seconds
  64. }
  65. } catch {
  66. debugPrint(
  67. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to calculate Override Target with error: \(error.localizedDescription)"
  68. )
  69. }
  70. return nil
  71. }
  72. static func calculateTarget(objectID: NSManagedObjectID, context: NSManagedObjectContext) -> Decimal? {
  73. do {
  74. if let override = try context.existingObject(with: objectID) as? OverrideStored,
  75. let overrideTarget = override.target, overrideTarget != 0
  76. {
  77. return overrideTarget.decimalValue
  78. }
  79. } catch {
  80. debugPrint(
  81. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to calculate Override Target with error: \(error.localizedDescription)"
  82. )
  83. }
  84. return nil
  85. }
  86. }