FaultEventCode.swift 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. //
  2. // FaultEventCode.swift
  3. // OmniKit
  4. //
  5. // Created by Pete Schwamb on 9/28/18.
  6. // Copyright © 2018 Pete Schwamb. All rights reserved.
  7. //
  8. import Foundation
  9. public struct FaultEventCode: CustomStringConvertible, Equatable {
  10. public let rawValue: UInt8
  11. public enum FaultEventType: UInt8 {
  12. case noFaults = 0x00
  13. case failedFlashErase = 0x01
  14. case failedFlashStore = 0x02
  15. case tableCorruptionBasalSubcommand = 0x03
  16. case corruptionByte720 = 0x05
  17. case dataCorruptionInTestRTCInterrupt = 0x06
  18. case rtcInterruptHandlerInconsistentState = 0x07
  19. case valueGreaterThan8 = 0x08
  20. case bf0notEqualToBF1 = 0x0A
  21. case tableCorruptionTempBasalSubcommand = 0x0B
  22. case resetDueToCOP = 0x0D
  23. case resetDueToIllegalOpcode = 0x0E
  24. case resetDueToIllegalAddress = 0x0F
  25. case resetDueToSAWCOP = 0x10
  26. case corruptionInByte_866 = 0x11
  27. case resetDueToLVD = 0x12
  28. case messageLengthTooLong = 0x13
  29. case occluded = 0x14
  30. case corruptionInWord129 = 0x15
  31. case corruptionInByte868 = 0x16
  32. case corruptionInAValidatedTable = 0x17
  33. case reservoirEmpty = 0x18
  34. case badPowerSwitchArrayValue1 = 0x19
  35. case badPowerSwitchArrayValue2 = 0x1A
  36. case badLoadCnthValue = 0x1B
  37. case exceededMaximumPodLife80Hrs = 0x1C
  38. case badStateCommand1AScheduleParse = 0x1D
  39. case unexpectedStateInRegisterUponReset = 0x1E
  40. case wrongSummaryForTable129 = 0x1F
  41. case validateCountErrorWhenBolusing = 0x20
  42. case badTimerVariableState = 0x21
  43. case unexpectedRTCModuleValueDuringReset = 0x22
  44. case problemCalibrateTimer = 0x23
  45. case rtcInterruptHandlerUnexpectedCall = 0x26
  46. case missing2hourAlertToFillTank = 0x27
  47. case faultEventSetupPod = 0x28
  48. case errorMainLoopHelper0 = 0x29
  49. case errorMainLoopHelper1 = 0x2A
  50. case errorMainLoopHelper2 = 0x2B
  51. case errorMainLoopHelper3 = 0x2C
  52. case errorMainLoopHelper4 = 0x2D
  53. case errorMainLoopHelper5 = 0x2E
  54. case errorMainLoopHelper6 = 0x2F
  55. case errorMainLoopHelper7 = 0x30
  56. case insulinDeliveryCommandError = 0x31
  57. case badValueStartupTest = 0x32
  58. case connectedPodCommandTimeout = 0x33
  59. case resetFromUnknownCause = 0x34
  60. case errorFlashInitialization = 0x36
  61. case badPiezoValue = 0x37
  62. case unexpectedValueByte358 = 0x38
  63. case problemWithLoad1and2 = 0x39
  64. case aGreaterThan7inMessage = 0x3A
  65. case failedTestSawReset = 0x3B
  66. case testInProgress = 0x3C
  67. case problemWithPumpAnchor = 0x3D
  68. case errorFlashWrite = 0x3E
  69. case encoderCountTooHigh = 0x40
  70. case encoderCountExcessiveVariance = 0x41
  71. case encoderCountTooLow = 0x42
  72. case encoderCountProblem = 0x43
  73. case checkVoltageOpenWire1 = 0x44
  74. case checkVoltageOpenWire2 = 0x45
  75. case problemWithLoad1and2type46 = 0x46
  76. case problemWithLoad1and2type47 = 0x47
  77. case badTimerCalibration = 0x48
  78. case badTimerRatios = 0x49
  79. case badTimerValues = 0x4A
  80. case trimICSTooCloseTo0x1FF = 0x4B
  81. case problemFindingBestTrimValue = 0x4C
  82. case badSetTPM1MultiCasesValue = 0x4D
  83. case unexpectedRFErrorFlagDuringReset = 0x4F
  84. case badCheckSdrhAndByte11FState = 0x51
  85. case issueTXOKprocessInputBuffer = 0x52
  86. case wrongValueWord_107 = 0x53
  87. case packetFrameLengthTooLong = 0x54
  88. case unexpectedIRQHighinTimerTick = 0x55
  89. case unexpectedIRQLowinTimerTick = 0x56
  90. case badArgToGetEntry = 0x57
  91. case badArgToUpdate37ATable = 0x58
  92. case errorUpdating37ATable = 0x59
  93. case occlusionCheckValueTooHigh = 0x5A
  94. case loadTableCorruption = 0x5B
  95. case primeOpenCountTooLow = 0x5C
  96. case badValueByte109 = 0x5D
  97. case disableFlashSecurityFailed = 0x5E
  98. case checkVoltageFailure = 0x5F
  99. case occlusionCheckStartup1 = 0x60
  100. case occlusionCheckStartup2 = 0x61
  101. case occlusionCheckTimeouts1 = 0x62
  102. case occlusionCheckTimeouts2 = 0x66
  103. case occlusionCheckTimeouts3 = 0x67
  104. case occlusionCheckPulseIssue = 0x68
  105. case occlusionCheckBolusProblem = 0x69
  106. case occlusionCheckAboveThreshold = 0x6A
  107. case basalUnderInfusion = 0x80
  108. case basalOverInfusion = 0x81
  109. case tempBasalUnderInfusion = 0x82
  110. case tempBasalOverInfusion = 0x83
  111. case bolusUnderInfusion = 0x84
  112. case bolusOverInfusion = 0x85
  113. case basalOverInfusionPulse = 0x86
  114. case tempBasalOverInfusionPulse = 0x87
  115. case bolusOverInfusionPulse = 0x88
  116. case immediateBolusOverInfusionPulse = 0x89
  117. case extendedBolusOverInfusionPulse = 0x8A
  118. case corruptionOfTables = 0x8B
  119. case badInputToVerifyAndStartPump = 0x8D
  120. case badPumpReq5State = 0x8E
  121. case command1AParseUnexpectedFailed = 0x8F
  122. case badValueForTables = 0x90
  123. case badPumpReq1State = 0x91
  124. case badPumpReq2State = 0x92
  125. case badPumpReq3State = 0x93
  126. case badValueField6in0x1A = 0x95
  127. case badStateInClearBolusIST2AndVars = 0x96
  128. case badStateInMaybeInc33D = 0x97
  129. case valuesDoNotMatchOrAreGreaterThan0x97 = 0x98
  130. }
  131. public var faultType: FaultEventType? {
  132. return FaultEventType(rawValue: rawValue)
  133. }
  134. init(rawValue: UInt8) {
  135. self.rawValue = rawValue
  136. }
  137. public var description: String {
  138. let faultDescription: String
  139. if let faultType = faultType {
  140. faultDescription = {
  141. switch faultType {
  142. case .noFaults:
  143. return "No fault"
  144. case .failedFlashErase:
  145. return "Flash erase failed"
  146. case .failedFlashStore:
  147. return "Flash store failed"
  148. case .tableCorruptionBasalSubcommand:
  149. return "Basal subcommand table corruption"
  150. case .corruptionByte720:
  151. return "Corruption in byte_720"
  152. case .dataCorruptionInTestRTCInterrupt:
  153. return "Data corruption error in test_RTC_interrupt"
  154. case .rtcInterruptHandlerInconsistentState:
  155. return "RTC interrupt handler called with inconstent state"
  156. case .valueGreaterThan8:
  157. return "Value > 8"
  158. case .bf0notEqualToBF1:
  159. return "Corruption in byte_BF0"
  160. case .tableCorruptionTempBasalSubcommand:
  161. return "Temp basal subcommand table corruption"
  162. case .resetDueToCOP:
  163. return "Reset due to COP"
  164. case .resetDueToIllegalOpcode:
  165. return "Reset due to illegal opcode"
  166. case .resetDueToIllegalAddress:
  167. return "Reset due to illegal address"
  168. case .resetDueToSAWCOP:
  169. return "Reset due to SAWCOP"
  170. case .corruptionInByte_866:
  171. return "Corruption in byte_866"
  172. case .resetDueToLVD:
  173. return "Reset due to LVD"
  174. case .messageLengthTooLong:
  175. return "Message length too long"
  176. case .occluded:
  177. return "Occluded"
  178. case .corruptionInWord129:
  179. return "Corruption in word_129 table/word_86A/dword_86E"
  180. case .corruptionInByte868:
  181. return "Corruption in byte_868"
  182. case .corruptionInAValidatedTable:
  183. return "Corruption in a validated table"
  184. case .reservoirEmpty:
  185. return "Reservoir empty or exceeded maximum pulse delivery"
  186. case .badPowerSwitchArrayValue1:
  187. return "Bad Power Switch Array Status and Control Register value 1 before starting pump"
  188. case .badPowerSwitchArrayValue2:
  189. return "Bad Power Switch Array Status and Control Register value 2 before starting pump"
  190. case .badLoadCnthValue:
  191. return "Bad LOADCNTH value when running pump"
  192. case .exceededMaximumPodLife80Hrs:
  193. return "Exceeded maximum Pod life of 80 hours"
  194. case .badStateCommand1AScheduleParse:
  195. return "Unexpected internal state in command_1A_schedule_parse_routine_wrapper"
  196. case .unexpectedStateInRegisterUponReset:
  197. return "Unexpected commissioned state in status and control register upon reset"
  198. case .wrongSummaryForTable129:
  199. return "Sum mismatch for word_129 table"
  200. case .validateCountErrorWhenBolusing:
  201. return "Validate encoder count error when bolusing"
  202. case .badTimerVariableState:
  203. return "Bad timer variable state"
  204. case .unexpectedRTCModuleValueDuringReset:
  205. return "Unexpected RTC Modulo Register value during reset"
  206. case .problemCalibrateTimer:
  207. return "Problem in calibrate_timer_case_3"
  208. case .rtcInterruptHandlerUnexpectedCall:
  209. return "RTC interrupt handler unexpectedly called"
  210. case .missing2hourAlertToFillTank:
  211. return "Failed to set up 2 hour alert for tank fill operation"
  212. case .faultEventSetupPod:
  213. return "Bad arg or state in update_insulin_variables, verify_and_start_pump or main_loop_control_pump"
  214. case .errorMainLoopHelper0:
  215. return "Alert #0 auto-off timeout"
  216. case .errorMainLoopHelper1:
  217. return "Alert #1 auto-off timeout"
  218. case .errorMainLoopHelper2:
  219. return "Alert #2 auto-off timeout"
  220. case .errorMainLoopHelper3:
  221. return "Alert #3 auto-off timeout"
  222. case .errorMainLoopHelper4:
  223. return "Alert #4 auto-off timeout"
  224. case .errorMainLoopHelper5:
  225. return "Alert #5 auto-off timeout"
  226. case .errorMainLoopHelper6:
  227. return "Alert #6 auto-off timeout"
  228. case .errorMainLoopHelper7:
  229. return "Alert #7 auto-off timeout"
  230. case .insulinDeliveryCommandError:
  231. return "Incorrect pod state for command or error during insulin command setup"
  232. case .badValueStartupTest:
  233. return "Bad value during startup testing"
  234. case .connectedPodCommandTimeout:
  235. return "Connected Pod command timeout"
  236. case .resetFromUnknownCause:
  237. return "Reset from unknown cause"
  238. case .errorFlashInitialization:
  239. return "Flash initialization error"
  240. case .badPiezoValue:
  241. return "Bad piezo value"
  242. case .unexpectedValueByte358:
  243. return "Unexpected byte_358 value"
  244. case .problemWithLoad1and2:
  245. return "Problem with LOAD1/LOAD2"
  246. case .aGreaterThan7inMessage:
  247. return "A > 7 in message processing"
  248. case .failedTestSawReset:
  249. return "SAW reset testing fail"
  250. case .testInProgress:
  251. return "402D is 'Z' - test in progress"
  252. case .problemWithPumpAnchor:
  253. return "Problem with pump anchor"
  254. case .errorFlashWrite:
  255. return "Flash initialization or write error"
  256. case .encoderCountTooHigh:
  257. return "Encoder count too high"
  258. case .encoderCountExcessiveVariance:
  259. return "Encoder count excessive variance"
  260. case .encoderCountTooLow:
  261. return "Encoder count too low"
  262. case .encoderCountProblem:
  263. return "Encoder count problem"
  264. case .checkVoltageOpenWire1:
  265. return "Check voltage open wire 1 problem"
  266. case .checkVoltageOpenWire2:
  267. return "Check voltage open wire 2 problem"
  268. case .problemWithLoad1and2type46:
  269. return "Problem with LOAD1/LOAD2"
  270. case .problemWithLoad1and2type47:
  271. return "Problem with LOAD1/LOAD2"
  272. case .badTimerCalibration:
  273. return "Bad timer calibration"
  274. case .badTimerRatios:
  275. return "Bad timer values: COP timer ratio bad"
  276. case .badTimerValues:
  277. return "Bad timer values"
  278. case .trimICSTooCloseTo0x1FF:
  279. return "ICS trim too close to 0x1FF"
  280. case .problemFindingBestTrimValue:
  281. return "find_best_trim_value problem"
  282. case .badSetTPM1MultiCasesValue:
  283. return "Bad set_TPM1_multi_cases value"
  284. case .unexpectedRFErrorFlagDuringReset:
  285. return "Unexpected TXSCR2 RF Tranmission Error Flag set during reset"
  286. case .badCheckSdrhAndByte11FState:
  287. return "Bad check_SDIRH and byte_11F state before starting pump"
  288. case .issueTXOKprocessInputBuffer:
  289. return "TXOK issue in process_input_buffer"
  290. case .wrongValueWord_107:
  291. return "Wrong word_107 value during input message processing"
  292. case .packetFrameLengthTooLong:
  293. return "Packet frame length too long"
  294. case .unexpectedIRQHighinTimerTick:
  295. return "Unexpected IRQ high in timer_tick"
  296. case .unexpectedIRQLowinTimerTick:
  297. return "Unexpected IRQ low in timer_tick"
  298. case .badArgToGetEntry:
  299. return "Corrupt constants table at byte_37A[] or flash byte_4036[]"
  300. case .badArgToUpdate37ATable:
  301. return "Bad argument to update_37A_table"
  302. case .errorUpdating37ATable:
  303. return "Error updating constants byte_37A table"
  304. case .occlusionCheckValueTooHigh:
  305. return "Occlusion check value too high for detection"
  306. case .loadTableCorruption:
  307. return "Load table corruption"
  308. case .primeOpenCountTooLow:
  309. return "Prime open count too low"
  310. case .badValueByte109:
  311. return "Bad byte_109 value"
  312. case .disableFlashSecurityFailed:
  313. return "Write flash byte to disable flash security failed"
  314. case .checkVoltageFailure:
  315. return "Two check voltage failures before starting pump"
  316. case .occlusionCheckStartup1:
  317. return "Occlusion check startup problem 1"
  318. case .occlusionCheckStartup2:
  319. return "Occlusion check startup problem 2"
  320. case .occlusionCheckTimeouts1:
  321. return "Occlusion check excess timeouts 1"
  322. case .occlusionCheckTimeouts2:
  323. return "Occlusion check excess timeouts 2"
  324. case .occlusionCheckTimeouts3:
  325. return "Occlusion check excess timeouts 3"
  326. case .occlusionCheckPulseIssue:
  327. return "Occlusion check pulse issue"
  328. case .occlusionCheckBolusProblem:
  329. return "Occlusion check bolus problem"
  330. case .occlusionCheckAboveThreshold:
  331. return "Occlusion check above threshold"
  332. case .basalUnderInfusion:
  333. return "Basal under infusion"
  334. case .basalOverInfusion:
  335. return "Basal over infusion"
  336. case .tempBasalUnderInfusion:
  337. return "Temp basal under infusion"
  338. case .tempBasalOverInfusion:
  339. return "Temp basal over infusion"
  340. case .bolusUnderInfusion:
  341. return "Bolus under infusion"
  342. case .bolusOverInfusion:
  343. return "Bolus over infusion"
  344. case .basalOverInfusionPulse:
  345. return "Basal over infusion pulse"
  346. case .tempBasalOverInfusionPulse:
  347. return "Temp basal over infusion pulse"
  348. case .bolusOverInfusionPulse:
  349. return "Bolus over infusion pulse"
  350. case .immediateBolusOverInfusionPulse:
  351. return "Immediate bolus under infusion pulse"
  352. case .extendedBolusOverInfusionPulse:
  353. return "Extended bolus over infusion pulse"
  354. case .corruptionOfTables:
  355. return "Corruption of $283/$2E3/$315 tables"
  356. case .badInputToVerifyAndStartPump:
  357. return "Bad input value to verify_and_start_pump"
  358. case .badPumpReq5State:
  359. return "Pump req 5 with basal IST not set or temp basal IST set"
  360. case .command1AParseUnexpectedFailed:
  361. return "Command 1A parse routine unexpected failed"
  362. case .badValueForTables:
  363. return "Bad value for $283/$2E3/$315 table specification"
  364. case .badPumpReq1State:
  365. return "Pump request 1 with temp basal IST not set"
  366. case .badPumpReq2State:
  367. return "Pump request 2 with temp basal IST not set"
  368. case .badPumpReq3State:
  369. return "Pump request 3 and bolus IST not set when about to pulse"
  370. case .badValueField6in0x1A:
  371. return "Bad table specifier field6 in 1A command"
  372. case .badStateInClearBolusIST2AndVars:
  373. return "Bad variable state in clear_Bolus_IST2_and_vars"
  374. case .badStateInMaybeInc33D:
  375. return "Bad variable state in maybe_inc_33D"
  376. case .valuesDoNotMatchOrAreGreaterThan0x97:
  377. return "Unknown fault code"
  378. }
  379. }()
  380. } else {
  381. faultDescription = "Unknown Fault"
  382. }
  383. return String(format: "Fault Event Code 0x%02x: %@", rawValue, faultDescription)
  384. }
  385. public var localizedDescription: String {
  386. if let faultType = faultType {
  387. switch faultType {
  388. case .noFaults:
  389. return LocalizedString("No faults", comment: "Description for Fault Event Code .noFaults")
  390. case .reservoirEmpty:
  391. return LocalizedString("Empty reservoir", comment: "Description for Empty reservoir pod fault")
  392. case .exceededMaximumPodLife80Hrs:
  393. return LocalizedString("Pod expired", comment: "Description for Pod expired pod fault")
  394. case .occluded:
  395. return LocalizedString("Occlusion detected", comment: "Description for Occlusion detected pod fault")
  396. default:
  397. return String(format: LocalizedString("Internal pod fault %1$03d", comment: "The format string for Internal pod fault (1: The fault code value)"), rawValue)
  398. }
  399. } else {
  400. return String(format: LocalizedString("Unknown pod fault %1$03d", comment: "The format string for Unknown pod fault (1: The fault code value)"), rawValue)
  401. }
  402. }
  403. }