BloodGlucose.swift 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import Foundation
  2. import HealthKit
  3. import LoopKit
  4. struct BloodGlucose: JSON, Identifiable, Hashable {
  5. enum Direction: String, JSON {
  6. case tripleUp = "TripleUp"
  7. case doubleUp = "DoubleUp"
  8. case singleUp = "SingleUp"
  9. case fortyFiveUp = "FortyFiveUp"
  10. case flat = "Flat"
  11. case fortyFiveDown = "FortyFiveDown"
  12. case singleDown = "SingleDown"
  13. case doubleDown = "DoubleDown"
  14. case tripleDown = "TripleDown"
  15. case none = "NONE"
  16. case notComputable = "NOT COMPUTABLE"
  17. case rateOutOfRange = "RATE OUT OF RANGE"
  18. }
  19. var _id = UUID().uuidString
  20. var id: String {
  21. _id
  22. }
  23. var sgv: Int?
  24. var direction: Direction?
  25. let date: Decimal
  26. let dateString: Date
  27. let unfiltered: Decimal?
  28. let filtered: Decimal?
  29. let noise: Int?
  30. var glucose: Int?
  31. let type: String?
  32. var activationDate: Date? = nil
  33. var sessionStartDate: Date? = nil
  34. var transmitterID: String? = nil
  35. var isStateValid: Bool { sgv ?? 0 >= 39 && noise ?? 1 != 4 }
  36. static func == (lhs: BloodGlucose, rhs: BloodGlucose) -> Bool {
  37. lhs.dateString == rhs.dateString
  38. }
  39. func hash(into hasher: inout Hasher) {
  40. hasher.combine(dateString)
  41. }
  42. }
  43. enum GlucoseUnits: String, JSON, Equatable {
  44. case mgdL = "mg/dL"
  45. case mmolL = "mmol/L"
  46. static let exchangeRate: Decimal = 0.0555
  47. }
  48. extension Int {
  49. var asMmolL: Decimal {
  50. FreeAPS.rounded(Decimal(self) * GlucoseUnits.exchangeRate, scale: 1, roundingMode: .plain)
  51. }
  52. }
  53. extension Decimal {
  54. var asMmolL: Decimal {
  55. FreeAPS.rounded(self * GlucoseUnits.exchangeRate, scale: 1, roundingMode: .plain)
  56. }
  57. var asMgdL: Decimal {
  58. FreeAPS.rounded(self / GlucoseUnits.exchangeRate, scale: 0, roundingMode: .plain)
  59. }
  60. }
  61. extension Double {
  62. var asMmolL: Decimal {
  63. FreeAPS.rounded(Decimal(self) * GlucoseUnits.exchangeRate, scale: 1, roundingMode: .plain)
  64. }
  65. var asMgdL: Decimal {
  66. FreeAPS.rounded(Decimal(self) / GlucoseUnits.exchangeRate, scale: 0, roundingMode: .plain)
  67. }
  68. }
  69. extension BloodGlucose: SavitzkyGolaySmoothable {
  70. var value: Double {
  71. get {
  72. Double(glucose ?? 0)
  73. }
  74. set {
  75. glucose = Int(newValue)
  76. sgv = Int(newValue)
  77. }
  78. }
  79. }
  80. extension BloodGlucose {
  81. func convertStoredGlucoseSample(device: HKDevice?) -> StoredGlucoseSample {
  82. StoredGlucoseSample(
  83. syncIdentifier: id,
  84. startDate: dateString.date,
  85. quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose!)),
  86. device: device
  87. )
  88. }
  89. }