Preferences.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import Foundation
  2. struct Preferences: JSON, Equatable {
  3. var maxIOB: Decimal = 0
  4. var maxDailySafetyMultiplier: Decimal = 3
  5. var currentBasalSafetyMultiplier: Decimal = 4
  6. var autosensMax: Decimal = 1.2
  7. var autosensMin: Decimal = 0.7
  8. var smbDeliveryRatio: Decimal = 0.5
  9. var rewindResetsAutosens: Bool = true
  10. var highTemptargetRaisesSensitivity: Bool = false
  11. var lowTemptargetLowersSensitivity: Bool = false
  12. var sensitivityRaisesTarget: Bool = false
  13. var resistanceLowersTarget: Bool = false
  14. var advTargetAdjustments: Bool = false
  15. var exerciseMode: Bool = false
  16. var halfBasalExerciseTarget: Decimal = 160
  17. var maxCOB: Decimal = 120
  18. var wideBGTargetRange: Bool = false
  19. var skipNeutralTemps: Bool = false
  20. var unsuspendIfNoTemp: Bool = false
  21. var min5mCarbimpact: Decimal = 8
  22. var autotuneISFAdjustmentFraction: Decimal = 1.0
  23. var remainingCarbsFraction: Decimal = 1.0
  24. var remainingCarbsCap: Decimal = 90
  25. var enableUAM: Bool = false
  26. var a52RiskEnable: Bool = false
  27. var enableSMBWithCOB: Bool = false
  28. var enableSMBWithTemptarget: Bool = false
  29. var enableSMBAlways: Bool = false
  30. var enableSMBAfterCarbs: Bool = false
  31. var allowSMBWithHighTemptarget: Bool = false
  32. var maxSMBBasalMinutes: Decimal = 30
  33. var maxUAMSMBBasalMinutes: Decimal = 30
  34. var smbInterval: Decimal = 3
  35. var bolusIncrement: Decimal = 0.1
  36. var curve: InsulinCurve = .rapidActing
  37. var useCustomPeakTime: Bool = false
  38. var insulinPeakTime: Decimal = 75
  39. var carbsReqThreshold: Decimal = 1.0
  40. var noisyCGMTargetMultiplier: Decimal = 1.3
  41. var suspendZerosIOB: Bool = false
  42. var timestamp: Date?
  43. var maxDeltaBGthreshold: Decimal = 0.2
  44. var adjustmentFactor: Decimal = 0.8
  45. var adjustmentFactorSigmoid: Decimal = 0.5
  46. var sigmoid: Bool = false
  47. var enableDynamicCR: Bool = false
  48. var useNewFormula: Bool = false
  49. var useWeightedAverage: Bool = false
  50. var weightPercentage: Decimal = 0.65
  51. var tddAdjBasal: Bool = false
  52. var enableSMB_high_bg: Bool = false
  53. var enableSMB_high_bg_target: Decimal = 110
  54. var threshold_setting: Decimal = 60
  55. var updateInterval: Decimal = 20
  56. }
  57. extension Preferences {
  58. private enum CodingKeys: String, CodingKey {
  59. case maxIOB = "max_iob"
  60. case maxDailySafetyMultiplier = "max_daily_safety_multiplier"
  61. case currentBasalSafetyMultiplier = "current_basal_safety_multiplier"
  62. case autosensMax = "autosens_max"
  63. case autosensMin = "autosens_min"
  64. case smbDeliveryRatio = "smb_delivery_ratio"
  65. case rewindResetsAutosens = "rewind_resets_autosens"
  66. case highTemptargetRaisesSensitivity = "high_temptarget_raises_sensitivity"
  67. case lowTemptargetLowersSensitivity = "low_temptarget_lowers_sensitivity"
  68. case sensitivityRaisesTarget = "sensitivity_raises_target"
  69. case resistanceLowersTarget = "resistance_lowers_target"
  70. case advTargetAdjustments = "adv_target_adjustments"
  71. case exerciseMode = "exercise_mode"
  72. case halfBasalExerciseTarget = "half_basal_exercise_target"
  73. case maxCOB
  74. case wideBGTargetRange = "wide_bg_target_range"
  75. case skipNeutralTemps = "skip_neutral_temps"
  76. case unsuspendIfNoTemp = "unsuspend_if_no_temp"
  77. case min5mCarbimpact = "min_5m_carbimpact"
  78. case autotuneISFAdjustmentFraction = "autotune_isf_adjustmentFraction"
  79. case remainingCarbsFraction
  80. case remainingCarbsCap
  81. case enableUAM
  82. case a52RiskEnable = "A52_risk_enable"
  83. case enableSMBWithCOB = "enableSMB_with_COB"
  84. case enableSMBWithTemptarget = "enableSMB_with_temptarget"
  85. case enableSMBAlways = "enableSMB_always"
  86. case enableSMBAfterCarbs = "enableSMB_after_carbs"
  87. case allowSMBWithHighTemptarget = "allowSMB_with_high_temptarget"
  88. case maxSMBBasalMinutes
  89. case maxUAMSMBBasalMinutes
  90. case smbInterval = "SMBInterval"
  91. case bolusIncrement = "bolus_increment"
  92. case curve
  93. case useCustomPeakTime
  94. case insulinPeakTime
  95. case carbsReqThreshold
  96. case noisyCGMTargetMultiplier
  97. case suspendZerosIOB = "suspend_zeros_iob"
  98. case maxDeltaBGthreshold = "maxDelta_bg_threshold"
  99. case adjustmentFactor
  100. case adjustmentFactorSigmoid
  101. case sigmoid
  102. case enableDynamicCR
  103. case useNewFormula
  104. case useWeightedAverage
  105. case weightPercentage
  106. case tddAdjBasal
  107. case enableSMB_high_bg
  108. case enableSMB_high_bg_target
  109. case threshold_setting
  110. case updateInterval
  111. }
  112. }
  113. enum InsulinCurve: String, JSON, Identifiable, CaseIterable {
  114. case rapidActing = "rapid-acting"
  115. case ultraRapid = "ultra-rapid"
  116. case bilinear
  117. var id: InsulinCurve { self }
  118. }
  119. extension Preferences: Decodable {
  120. init(from decoder: Decoder) throws {
  121. let container = try decoder.container(keyedBy: CodingKeys.self)
  122. var preferences = Preferences()
  123. if let maxIOB = try? container.decode(Decimal.self, forKey: .maxIOB) {
  124. preferences.maxIOB = maxIOB
  125. }
  126. if let maxDailySafetyMultiplier = try? container.decode(Decimal.self, forKey: .maxDailySafetyMultiplier) {
  127. preferences.maxDailySafetyMultiplier = maxDailySafetyMultiplier
  128. }
  129. if let currentBasalSafetyMultiplier = try? container.decode(Decimal.self, forKey: .currentBasalSafetyMultiplier) {
  130. preferences.currentBasalSafetyMultiplier = currentBasalSafetyMultiplier
  131. }
  132. if let autosensMax = try? container.decode(Decimal.self, forKey: .autosensMax) {
  133. preferences.autosensMax = autosensMax
  134. }
  135. if let autosensMin = try? container.decode(Decimal.self, forKey: .autosensMin) {
  136. preferences.autosensMin = autosensMin
  137. }
  138. if let smbDeliveryRatio = try? container.decode(Decimal.self, forKey: .smbDeliveryRatio) {
  139. preferences.smbDeliveryRatio = smbDeliveryRatio
  140. }
  141. if let rewindResetsAutosens = try? container.decode(Bool.self, forKey: .rewindResetsAutosens) {
  142. preferences.rewindResetsAutosens = rewindResetsAutosens
  143. }
  144. if let highTemptargetRaisesSensitivity = try? container.decode(Bool.self, forKey: .highTemptargetRaisesSensitivity) {
  145. preferences.highTemptargetRaisesSensitivity = highTemptargetRaisesSensitivity
  146. }
  147. if let lowTemptargetLowersSensitivity = try? container.decode(Bool.self, forKey: .lowTemptargetLowersSensitivity) {
  148. preferences.lowTemptargetLowersSensitivity = lowTemptargetLowersSensitivity
  149. }
  150. if let sensitivityRaisesTarget = try? container.decode(Bool.self, forKey: .sensitivityRaisesTarget) {
  151. preferences.sensitivityRaisesTarget = sensitivityRaisesTarget
  152. }
  153. if let resistanceLowersTarget = try? container.decode(Bool.self, forKey: .resistanceLowersTarget) {
  154. preferences.resistanceLowersTarget = resistanceLowersTarget
  155. }
  156. if let advTargetAdjustments = try? container.decode(Bool.self, forKey: .advTargetAdjustments) {
  157. preferences.advTargetAdjustments = advTargetAdjustments
  158. }
  159. if let exerciseMode = try? container.decode(Bool.self, forKey: .exerciseMode) {
  160. preferences.exerciseMode = exerciseMode
  161. }
  162. if let halfBasalExerciseTarget = try? container.decode(Decimal.self, forKey: .halfBasalExerciseTarget) {
  163. preferences.halfBasalExerciseTarget = halfBasalExerciseTarget
  164. }
  165. if let maxCOB = try? container.decode(Decimal.self, forKey: .maxCOB) {
  166. preferences.maxCOB = maxCOB
  167. }
  168. if let wideBGTargetRange = try? container.decode(Bool.self, forKey: .wideBGTargetRange) {
  169. preferences.wideBGTargetRange = wideBGTargetRange
  170. }
  171. if let skipNeutralTemps = try? container.decode(Bool.self, forKey: .skipNeutralTemps) {
  172. preferences.skipNeutralTemps = skipNeutralTemps
  173. }
  174. if let unsuspendIfNoTemp = try? container.decode(Bool.self, forKey: .unsuspendIfNoTemp) {
  175. preferences.unsuspendIfNoTemp = unsuspendIfNoTemp
  176. }
  177. if let min5mCarbimpact = try? container.decode(Decimal.self, forKey: .min5mCarbimpact) {
  178. preferences.min5mCarbimpact = min5mCarbimpact
  179. }
  180. if let autotuneISFAdjustmentFraction = try? container.decode(Decimal.self, forKey: .autotuneISFAdjustmentFraction) {
  181. preferences.autotuneISFAdjustmentFraction = autotuneISFAdjustmentFraction
  182. }
  183. if let remainingCarbsFraction = try? container.decode(Decimal.self, forKey: .remainingCarbsFraction) {
  184. preferences.remainingCarbsFraction = remainingCarbsFraction
  185. }
  186. if let remainingCarbsCap = try? container.decode(Decimal.self, forKey: .remainingCarbsCap) {
  187. preferences.remainingCarbsCap = remainingCarbsCap
  188. }
  189. if let enableUAM = try? container.decode(Bool.self, forKey: .enableUAM) {
  190. preferences.enableUAM = enableUAM
  191. }
  192. if let a52RiskEnable = try? container.decode(Bool.self, forKey: .a52RiskEnable) {
  193. preferences.a52RiskEnable = a52RiskEnable
  194. }
  195. if let enableSMBWithCOB = try? container.decode(Bool.self, forKey: .enableSMBWithCOB) {
  196. preferences.enableSMBWithCOB = enableSMBWithCOB
  197. }
  198. if let enableSMBWithTemptarget = try? container.decode(Bool.self, forKey: .enableSMBWithTemptarget) {
  199. preferences.enableSMBWithTemptarget = enableSMBWithTemptarget
  200. }
  201. if let enableSMBAlways = try? container.decode(Bool.self, forKey: .enableSMBAlways) {
  202. preferences.enableSMBAlways = enableSMBAlways
  203. }
  204. if let enableSMBAfterCarbs = try? container.decode(Bool.self, forKey: .enableSMBAfterCarbs) {
  205. preferences.enableSMBAfterCarbs = enableSMBAfterCarbs
  206. }
  207. if let allowSMBWithHighTemptarget = try? container.decode(Bool.self, forKey: .allowSMBWithHighTemptarget) {
  208. preferences.allowSMBWithHighTemptarget = allowSMBWithHighTemptarget
  209. }
  210. if let maxSMBBasalMinutes = try? container.decode(Decimal.self, forKey: .maxSMBBasalMinutes) {
  211. preferences.maxSMBBasalMinutes = maxSMBBasalMinutes
  212. }
  213. if let maxUAMSMBBasalMinutes = try? container.decode(Decimal.self, forKey: .maxUAMSMBBasalMinutes) {
  214. preferences.maxUAMSMBBasalMinutes = maxUAMSMBBasalMinutes
  215. }
  216. if let smbInterval = try? container.decode(Decimal.self, forKey: .smbInterval) {
  217. preferences.smbInterval = smbInterval
  218. }
  219. if let bolusIncrement = try? container.decode(Decimal.self, forKey: .bolusIncrement) {
  220. preferences.bolusIncrement = bolusIncrement
  221. }
  222. if let curve = try? container.decode(InsulinCurve.self, forKey: .curve) {
  223. preferences.curve = curve
  224. }
  225. if let useCustomPeakTime = try? container.decode(Bool.self, forKey: .useCustomPeakTime) {
  226. preferences.useCustomPeakTime = useCustomPeakTime
  227. }
  228. if let insulinPeakTime = try? container.decode(Decimal.self, forKey: .insulinPeakTime) {
  229. preferences.insulinPeakTime = insulinPeakTime
  230. }
  231. if let carbsReqThreshold = try? container.decode(Decimal.self, forKey: .carbsReqThreshold) {
  232. preferences.carbsReqThreshold = carbsReqThreshold
  233. }
  234. if let noisyCGMTargetMultiplier = try? container.decode(Decimal.self, forKey: .noisyCGMTargetMultiplier) {
  235. preferences.noisyCGMTargetMultiplier = noisyCGMTargetMultiplier
  236. }
  237. if let suspendZerosIOB = try? container.decode(Bool.self, forKey: .suspendZerosIOB) {
  238. preferences.suspendZerosIOB = suspendZerosIOB
  239. }
  240. if let maxDeltaBGthreshold = try? container.decode(Decimal.self, forKey: .maxDeltaBGthreshold) {
  241. preferences.maxDeltaBGthreshold = maxDeltaBGthreshold
  242. }
  243. if let adjustmentFactor = try? container.decode(Decimal.self, forKey: .adjustmentFactor) {
  244. preferences.adjustmentFactor = adjustmentFactor
  245. }
  246. if let adjustmentFactorSigmoid = try? container.decode(Decimal.self, forKey: .adjustmentFactorSigmoid) {
  247. preferences.adjustmentFactorSigmoid = adjustmentFactorSigmoid
  248. }
  249. if let sigmoid = try? container.decode(Bool.self, forKey: .sigmoid) {
  250. preferences.sigmoid = sigmoid
  251. }
  252. if let enableDynamicCR = try? container.decode(Bool.self, forKey: .enableDynamicCR) {
  253. preferences.enableDynamicCR = enableDynamicCR
  254. }
  255. if let useNewFormula = try? container.decode(Bool.self, forKey: .useNewFormula) {
  256. preferences.useNewFormula = useNewFormula
  257. }
  258. if let useWeightedAverage = try? container.decode(Bool.self, forKey: .useWeightedAverage) {
  259. preferences.useWeightedAverage = useWeightedAverage
  260. }
  261. if let weightPercentage = try? container.decode(Decimal.self, forKey: .weightPercentage) {
  262. preferences.weightPercentage = weightPercentage
  263. }
  264. if let tddAdjBasal = try? container.decode(Bool.self, forKey: .tddAdjBasal) {
  265. preferences.tddAdjBasal = tddAdjBasal
  266. }
  267. if let enableSMB_high_bg = try? container.decode(Bool.self, forKey: .enableSMB_high_bg) {
  268. preferences.enableSMB_high_bg = enableSMB_high_bg
  269. }
  270. if let enableSMB_high_bg_target = try? container.decode(Decimal.self, forKey: .enableSMB_high_bg_target) {
  271. preferences.enableSMB_high_bg_target = enableSMB_high_bg_target
  272. }
  273. if let threshold_setting = try? container.decode(Decimal.self, forKey: .threshold_setting) {
  274. preferences.threshold_setting = threshold_setting
  275. }
  276. if let updateInterval = try? container.decode(Decimal.self, forKey: .updateInterval) {
  277. preferences.updateInterval = updateInterval
  278. }
  279. self = preferences
  280. }
  281. }