PushMessage.swift 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import Foundation
  2. enum TRCCommandType: String, Codable {
  3. case bolus
  4. case tempTarget = "temp_target"
  5. case cancelTempTarget = "cancel_temp_target"
  6. case meal
  7. case startOverride = "start_override"
  8. case cancelOverride = "cancel_override"
  9. var description: String {
  10. switch self {
  11. case .bolus:
  12. return "Bolus"
  13. case .tempTarget:
  14. return "Temporary Target"
  15. case .cancelTempTarget:
  16. return "Cancel Temporary Target"
  17. case .meal:
  18. return "Meal"
  19. case .startOverride:
  20. return "Start Override"
  21. case .cancelOverride:
  22. return "Cancel Override"
  23. }
  24. }
  25. }
  26. struct PushMessage: Codable {
  27. var user: String
  28. var commandType: TRCCommandType
  29. var bolusAmount: Decimal?
  30. var target: Int?
  31. var duration: Int?
  32. var carbs: Int?
  33. var protein: Int?
  34. var fat: Int?
  35. var sharedSecret: String
  36. var timestamp: TimeInterval
  37. var overrideName: String?
  38. var scheduledTime: TimeInterval?
  39. enum CodingKeys: String, CodingKey {
  40. case aps
  41. case user
  42. case commandType = "command_type"
  43. case bolusAmount = "bolus_amount"
  44. case target
  45. case duration
  46. case carbs
  47. case protein
  48. case fat
  49. case sharedSecret = "shared_secret"
  50. case timestamp
  51. case overrideName
  52. case scheduledTime = "scheduled_time"
  53. }
  54. func encode(to encoder: Encoder) throws {
  55. var container = encoder.container(keyedBy: CodingKeys.self)
  56. try container.encode(user, forKey: .user)
  57. try container.encode(commandType, forKey: .commandType)
  58. try container.encodeIfPresent(bolusAmount, forKey: .bolusAmount)
  59. try container.encodeIfPresent(target, forKey: .target)
  60. try container.encodeIfPresent(duration, forKey: .duration)
  61. try container.encodeIfPresent(carbs, forKey: .carbs)
  62. try container.encodeIfPresent(protein, forKey: .protein)
  63. try container.encodeIfPresent(fat, forKey: .fat)
  64. try container.encode(sharedSecret, forKey: .sharedSecret)
  65. try container.encode(timestamp, forKey: .timestamp)
  66. try container.encodeIfPresent(overrideName, forKey: .overrideName)
  67. if let scheduledTime = scheduledTime {
  68. try container.encode(scheduledTime, forKey: .scheduledTime)
  69. }
  70. }
  71. init(from decoder: Decoder) throws {
  72. let container = try decoder.container(keyedBy: CodingKeys.self)
  73. user = try container.decode(String.self, forKey: .user)
  74. commandType = try container.decode(TRCCommandType.self, forKey: .commandType)
  75. bolusAmount = try container.decodeIfPresent(Decimal.self, forKey: .bolusAmount)
  76. target = try container.decodeIfPresent(Int.self, forKey: .target)
  77. duration = try container.decodeIfPresent(Int.self, forKey: .duration)
  78. carbs = try container.decodeIfPresent(Int.self, forKey: .carbs)
  79. protein = try container.decodeIfPresent(Int.self, forKey: .protein)
  80. fat = try container.decodeIfPresent(Int.self, forKey: .fat)
  81. sharedSecret = try container.decode(String.self, forKey: .sharedSecret)
  82. timestamp = try container.decode(TimeInterval.self, forKey: .timestamp)
  83. overrideName = try container.decodeIfPresent(String.self, forKey: .overrideName)
  84. scheduledTime = try container.decodeIfPresent(TimeInterval.self, forKey: .scheduledTime)
  85. }
  86. init(
  87. user: String,
  88. commandType: TRCCommandType,
  89. bolusAmount: Decimal? = nil,
  90. target: Int? = nil,
  91. duration: Int? = nil,
  92. carbs: Int? = nil,
  93. protein: Int? = nil,
  94. fat: Int? = nil,
  95. sharedSecret: String,
  96. timestamp: TimeInterval,
  97. overrideName: String? = nil,
  98. scheduledTime: TimeInterval? = nil
  99. ) {
  100. self.user = user
  101. self.commandType = commandType
  102. self.bolusAmount = bolusAmount
  103. self.target = target
  104. self.duration = duration
  105. self.carbs = carbs
  106. self.protein = protein
  107. self.fat = fat
  108. self.sharedSecret = sharedSecret
  109. self.timestamp = timestamp
  110. self.overrideName = overrideName
  111. self.scheduledTime = scheduledTime
  112. }
  113. func humanReadableDescription() -> String {
  114. var description = "User: \(user). Command Type: \(commandType.description). "
  115. if let override = overrideName {
  116. description += "Override Name: \(override). "
  117. }
  118. switch commandType {
  119. case .bolus:
  120. if let amount = bolusAmount {
  121. description += "Bolus Amount: \(amount) units."
  122. } else {
  123. description += "Bolus Amount: unknown."
  124. }
  125. case .tempTarget:
  126. let targetDesc = target != nil ? "\(target!) mg/dL" : "unknown target"
  127. let durationDesc = duration != nil ? "\(duration!) minutes" : "unknown duration"
  128. description += "Temp Target: \(targetDesc), Duration: \(durationDesc)."
  129. case .cancelTempTarget:
  130. description += "Cancel Temp Target command."
  131. case .meal:
  132. let carbsDesc = carbs != nil ? "\(carbs!)g carbs" : "unknown carbs"
  133. let fatDesc = fat != nil ? "\(fat!)g fat" : "unknown fat"
  134. let proteinDesc = protein != nil ? "\(protein!)g protein" : "unknown protein"
  135. description += "Meal with \(carbsDesc), \(fatDesc), \(proteinDesc)."
  136. case .startOverride:
  137. if let override = overrideName {
  138. description += "Start Override: \(override)."
  139. } else {
  140. description += "Start Override: unknown override name."
  141. }
  142. case .cancelOverride:
  143. description += "Cancel Override command."
  144. }
  145. if let scheduledTime = scheduledTime {
  146. let date = Date(timeIntervalSince1970: scheduledTime)
  147. let formatter = DateFormatter()
  148. formatter.dateStyle = .short
  149. formatter.timeStyle = .short
  150. let dateString = formatter.string(from: date)
  151. description += " Scheduled for: \(dateString)."
  152. }
  153. return description
  154. }
  155. }