Skip to content

Fix handling of comms error on resume & all pod DeliveryStatus cases #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions OmniBLE/OmnipodCommon/Pod.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,30 +97,33 @@ public struct Pod {
}

// DeliveryStatus used in StatusResponse and DetailedStatus
// Since bits 1 & 2 are exclusive and bits 4 & 8 are exclusive,
// these are all the possible values that can be returned.
public enum DeliveryStatus: UInt8, CustomStringConvertible {
case suspended = 0
case scheduledBasal = 1
case tempBasalRunning = 2
case priming = 4
case priming = 4 // bolusing while suspended, should only occur during priming
case bolusInProgress = 5
case bolusAndTempBasal = 6
case extendedBolusWhileSuspended = 8 // should never occur
case extendedBolusRunning = 9
case extendedBolusAndTempBasal = 10

public var suspended: Bool {
return self == .suspended
return self == .suspended || self == .priming || self == .extendedBolusWhileSuspended
}

public var bolusing: Bool {
return self == .bolusInProgress || self == .bolusAndTempBasal || self == .extendedBolusRunning || self == .extendedBolusAndTempBasal
return self == .bolusInProgress || self == .bolusAndTempBasal || self == .extendedBolusRunning || self == .extendedBolusAndTempBasal || self == .priming || self == .extendedBolusWhileSuspended
}

public var tempBasalRunning: Bool {
return self == .tempBasalRunning || self == .bolusAndTempBasal || self == .extendedBolusAndTempBasal
}

public var extendedBolusRunning: Bool {
return self == .extendedBolusRunning || self == .extendedBolusAndTempBasal
return self == .extendedBolusRunning || self == .extendedBolusAndTempBasal || self == .extendedBolusWhileSuspended
}

public var description: String {
Expand All @@ -137,6 +140,8 @@ public enum DeliveryStatus: UInt8, CustomStringConvertible {
return LocalizedString("Bolusing", comment: "Delivery status when bolusing")
case .bolusAndTempBasal:
return LocalizedString("Bolusing with temp basal", comment: "Delivery status when bolusing and temp basal is running")
case .extendedBolusWhileSuspended:
return LocalizedString("Extended bolus running while suspended", comment: "Delivery status when extended bolus is running while suspended")
case .extendedBolusRunning:
return LocalizedString("Extended bolus running", comment: "Delivery status when extended bolus is running")
case .extendedBolusAndTempBasal:
Expand Down
8 changes: 5 additions & 3 deletions OmniBLE/PumpManager/OmniBLEPumpManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1848,7 +1848,7 @@ extension OmniBLEPumpManager: PumpManager {
state.bolusEngageState = .engaging
})

if case .some(.suspended) = self.state.podState?.suspendState {
if let podState = self.state.podState, podState.isSuspended || podState.lastDeliveryStatusReceived?.suspended != false {
self.log.error("enactBolus: returning pod suspended error for bolus")
completion(.deviceState(PodCommsError.podSuspended))
return
Expand Down Expand Up @@ -1989,7 +1989,7 @@ extension OmniBLEPumpManager: PumpManager {
return
}

if case (.suspended) = podState.suspendState {
if let podState = self.state.podState, podState.isSuspended || podState.lastDeliveryStatusReceived?.suspended != false {
self.log.info("Not enacting temp basal because podState indicates pod is suspended.")
completion(.deviceState(PodCommsError.podSuspended))
return
Expand Down Expand Up @@ -2522,7 +2522,9 @@ extension OmniBLEPumpManager {
if alert.alertIdentifier == alertIdentifier || alert.repeatingAlertIdentifier == alertIdentifier {
// If this alert was triggered by the pod find the slot to clear it.
if let slot = alert.triggeringSlot {
if case .some(.suspended) = self.state.podState?.suspendState, slot == .slot6SuspendTimeExpired {
if (self.state.podState?.isSuspended == true || self.state.podState?.lastDeliveryStatusReceived?.suspended == true) &&
slot == .slot6SuspendTimeExpired
{
// Don't clear this pod alert here with the pod still suspended so that the suspend time expired
// pod alert beeping will continue until the pod is resumed which will then deactivate this alert.
log.default("Skipping acknowledgement of suspend time expired alert with a suspended pod")
Expand Down
12 changes: 7 additions & 5 deletions OmniBLE/PumpManager/PodCommsSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,9 @@ public class PodCommsSession {
let _: StatusResponse = try send([CancelDeliveryCommand(nonce: podState.currentNonce, deliveryType: .all, beepType: .noBeepCancel)])
}
}
podState.unacknowledgedCommand = PendingCommand.program(.basalProgram(schedule: schedule), transport.messageNumber, currentDate)
var status: StatusResponse = try send([basalScheduleCommand, basalExtraCommand])
podState.unacknowledgedCommand = nil
let now = currentDate
podState.suspendState = .resumed(now)
podState.unfinalizedResume = UnfinalizedDose(resumeStartTime: now, scheduledCertainty: .certain, insulinType: podState.insulinType)
Expand All @@ -813,12 +815,12 @@ public class PodCommsSession {
}
podState.updateFromStatusResponse(status, at: currentDate)
return status
} catch PodCommsError.nonceResyncFailed {
throw PodCommsError.nonceResyncFailed
} catch PodCommsError.rejectedMessage(let errorCode) {
throw PodCommsError.rejectedMessage(errorCode: errorCode)
} catch PodCommsError.unacknowledgedMessage(let seq, let error) {
podState.unacknowledgedCommand = podState.unacknowledgedCommand?.commsFinished
log.error("Unacknowledged resume: command seq = %d, error = %{public}@", seq, String(describing: error))
throw error
} catch let error {
podState.unfinalizedResume = UnfinalizedDose(resumeStartTime: currentDate, scheduledCertainty: .uncertain, insulinType: podState.insulinType)
podState.unacknowledgedCommand = nil
throw error
}
}
Expand Down