OpenAPSSwift.swift 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import Foundation
  2. struct OpenAPSSwift {
  3. static func makeProfile(
  4. preferences: JSON,
  5. pumpSettings: JSON,
  6. bgTargets: JSON,
  7. basalProfile: JSON,
  8. isf: JSON,
  9. carbRatio: JSON,
  10. tempTargets: JSON,
  11. model: JSON,
  12. trioSettings: JSON,
  13. clock: Date
  14. ) -> (OrefFunctionResult) {
  15. do {
  16. let preferences = try JSONBridge.preferences(from: preferences)
  17. let pumpSettings = try JSONBridge.pumpSettings(from: pumpSettings)
  18. let bgTargets = try JSONBridge.bgTargets(from: bgTargets)
  19. let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
  20. let isf = try JSONBridge.insulinSensitivities(from: isf)
  21. let carbRatio = try JSONBridge.carbRatios(from: carbRatio)
  22. let tempTargets = try JSONBridge.tempTargets(from: tempTargets)
  23. let model = JSONBridge.model(from: model)
  24. let trioSettings = try JSONBridge.trioSettings(from: trioSettings)
  25. let profile = try ProfileGenerator.generate(
  26. pumpSettings: pumpSettings,
  27. bgTargets: bgTargets,
  28. basalProfile: basalProfile,
  29. isf: isf,
  30. preferences: preferences,
  31. carbRatios: carbRatio,
  32. tempTargets: tempTargets,
  33. model: model,
  34. clock: clock
  35. )
  36. return (try .success(JSONBridge.to(profile)))
  37. } catch {
  38. return (.failure(error))
  39. }
  40. }
  41. static func determineBasal(
  42. glucose: JSON,
  43. currentTemp: JSON,
  44. iob: JSON,
  45. profile: JSON,
  46. autosens: JSON,
  47. meal: JSON,
  48. microBolusAllowed: Bool,
  49. reservoir: JSON,
  50. pumpHistory: JSON,
  51. preferences: JSON,
  52. basalProfile: JSON,
  53. trioCustomOrefVariables: JSON,
  54. clock: Date
  55. ) -> (OrefFunctionResult) {
  56. do {
  57. let glucose = try JSONBridge.glucose(from: glucose)
  58. let currentTemp = try JSONBridge.currentTemp(from: currentTemp)
  59. let iob = try JSONBridge.iobResult(from: iob)
  60. let profile = try JSONBridge.profile(from: profile)
  61. let autosens = try JSONBridge.autosens(from: autosens)
  62. let meal = try JSONBridge.computedCarbs(from: meal)
  63. let microBolusAllowed = microBolusAllowed
  64. let reservoir = Decimal(string: reservoir.rawJSON)
  65. let pumpHistory = try JSONBridge.pumpHistory(from: pumpHistory)
  66. let preferences = try JSONBridge.preferences(from: preferences)
  67. let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
  68. let trioCustomOrefVariables = try JSONBridge.trioCustomOrefVariables(from: trioCustomOrefVariables)
  69. guard let mealData = meal, let autosensData = autosens else {
  70. return .failure(DeterminationError.missingInputs)
  71. }
  72. let rawDetermination = try DeterminationGenerator.generate(
  73. profile: profile,
  74. preferences: preferences,
  75. currentTemp: currentTemp,
  76. iobData: iob,
  77. mealData: mealData,
  78. autosensData: autosensData,
  79. reservoirData: reservoir ?? 100,
  80. glucose: glucose,
  81. microBolusAllowed: microBolusAllowed,
  82. trioCustomOrefVariables: trioCustomOrefVariables,
  83. currentTime: clock
  84. )
  85. return try .success(JSONBridge.to(rawDetermination))
  86. } catch let determinationError as DeterminationError {
  87. // if we get a determination error we want to return it as a JSON
  88. // object that is { "error": "some error" }
  89. do {
  90. let response = try JSONBridge.to(DeterminationErrorResponse(error: determinationError.localizedDescription))
  91. return .success(response)
  92. } catch {
  93. return .failure(determinationError)
  94. }
  95. } catch {
  96. return .failure(error)
  97. }
  98. }
  99. static func meal(
  100. pumphistory: JSON,
  101. profile: JSON,
  102. basalProfile: JSON,
  103. clock: JSON,
  104. carbs: JSON,
  105. glucose: JSON
  106. ) -> (OrefFunctionResult) {
  107. do {
  108. let pumpHistory = try JSONBridge.pumpHistory(from: pumphistory)
  109. let profile = try JSONBridge.profile(from: profile)
  110. let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
  111. let clock = try JSONBridge.clock(from: clock)
  112. let carbs = try JSONBridge.carbs(from: carbs)
  113. let glucose = try JSONBridge.glucose(from: glucose)
  114. let mealResult = try MealGenerator.generate(
  115. pumpHistory: pumpHistory,
  116. profile: profile,
  117. basalProfile: basalProfile,
  118. clock: clock,
  119. carbHistory: carbs,
  120. glucoseHistory: glucose
  121. )
  122. return try .success(JSONBridge.to(mealResult))
  123. } catch {
  124. return .failure(error)
  125. }
  126. }
  127. static func iob(pumphistory: JSON, profile: JSON, clock: JSON, autosens: JSON) -> (OrefFunctionResult) {
  128. do {
  129. let pumpHistory = try JSONBridge.pumpHistory(from: pumphistory)
  130. let profile = try JSONBridge.profile(from: profile)
  131. let clock = try JSONBridge.clock(from: clock)
  132. let autosens = try JSONBridge.autosens(from: autosens)
  133. let iobResult = try IobGenerator.generate(
  134. history: pumpHistory,
  135. profile: profile,
  136. clock: clock,
  137. autosens: autosens
  138. )
  139. return try .success(JSONBridge.to(iobResult))
  140. } catch {
  141. return .failure(error)
  142. }
  143. }
  144. static func autosense(
  145. glucose: JSON,
  146. pumpHistory: JSON,
  147. basalProfile: JSON,
  148. profile: JSON,
  149. carbs: JSON,
  150. tempTargets: JSON,
  151. clock: JSON,
  152. includeDeviationsForTesting: Bool = false
  153. ) -> (OrefFunctionResult) {
  154. do {
  155. let glucose = try JSONBridge.glucose(from: glucose)
  156. let pumpHistory = try JSONBridge.pumpHistory(from: pumpHistory)
  157. let basalProfile = try JSONBridge.basalProfile(from: basalProfile)
  158. let profile = try JSONBridge.profile(from: profile)
  159. let carbs = try JSONBridge.carbs(from: carbs)
  160. let tempTargets = try JSONBridge.tempTargets(from: tempTargets)
  161. let clock = try JSONBridge.clock(from: clock)
  162. // this logic is from prepare/autosens.js
  163. let ratio8h = try AutosensGenerator.generate(
  164. glucose: glucose,
  165. pumpHistory: pumpHistory,
  166. basalProfile: basalProfile,
  167. profile: profile,
  168. carbs: carbs,
  169. tempTargets: tempTargets,
  170. maxDeviations: 96,
  171. clock: clock,
  172. includeDeviationsForTesting: includeDeviationsForTesting
  173. )
  174. let ratio24h = try AutosensGenerator.generate(
  175. glucose: glucose,
  176. pumpHistory: pumpHistory,
  177. basalProfile: basalProfile,
  178. profile: profile,
  179. carbs: carbs,
  180. tempTargets: tempTargets,
  181. maxDeviations: 288,
  182. clock: clock,
  183. includeDeviationsForTesting: includeDeviationsForTesting
  184. )
  185. let lowestRatio = ratio8h.ratio < ratio24h.ratio ? ratio8h : ratio24h
  186. return try .success(JSONBridge.to(lowestRatio))
  187. } catch {
  188. return .failure(error)
  189. }
  190. }
  191. }