enable beeps when delivery is suspended
This commit is contained in:
parent
ae573de63d
commit
e903c9c055
12 changed files with 238 additions and 12 deletions
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command
|
||||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand
|
||||
|
||||
class CommandDisableSuspendAlerts: CustomCommand {
|
||||
|
||||
override val statusDescription: String
|
||||
get() = "DISABLE SUSPEND ALERTS"
|
||||
}
|
|
@ -502,7 +502,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
// prevent setBasal requests
|
||||
return true
|
||||
}
|
||||
// TODO: what do we have to answer here if delivery is suspended?
|
||||
if (podStateManager.isSuspended) {
|
||||
// set new basal profile failed midway
|
||||
return false
|
||||
}
|
||||
val running = podStateManager.basalProgram
|
||||
val equal = (mapProfileToBasalProgram(profile) == running)
|
||||
aapsLogger.info(LTag.PUMP, "set: $equal. profile=$profile, running=$running")
|
||||
|
@ -1101,7 +1104,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
updateAlertConfiguration()
|
||||
is CommandPlayTestBeep ->
|
||||
playTestBeep()
|
||||
|
||||
is CommandDisableSuspendAlerts ->
|
||||
disableSuspendAlerts()
|
||||
else -> {
|
||||
aapsLogger.warn(LTag.PUMP, "Unsupported custom command: " + customCommand.javaClass.name)
|
||||
PumpEnactResult(injector).success(false).enacted(false).comment(
|
||||
|
@ -1114,6 +1118,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun silenceAlerts(): PumpEnactResult {
|
||||
// TODO filter alert types
|
||||
return podStateManager.activeAlerts?.let {
|
||||
|
@ -1124,6 +1129,41 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No active alerts") // TODO i18n
|
||||
}
|
||||
|
||||
private fun disableSuspendAlerts(): PumpEnactResult {
|
||||
val alerts = listOf(
|
||||
AlertConfiguration(
|
||||
AlertType.SUSPEND_IN_PROGRESS,
|
||||
enabled = false,
|
||||
durationInMinutes = 0,
|
||||
autoOff = false,
|
||||
AlertTrigger.TimerTrigger(
|
||||
0
|
||||
),
|
||||
BeepType.XXX,
|
||||
BeepRepetitionType.XXX4
|
||||
),
|
||||
AlertConfiguration(
|
||||
AlertType.SUSPEND_ENDED,
|
||||
enabled = false,
|
||||
durationInMinutes = 0,
|
||||
autoOff = false,
|
||||
AlertTrigger.TimerTrigger(
|
||||
0
|
||||
),
|
||||
BeepType.FOUR_TIMES_BIP_BEEP,
|
||||
BeepRepetitionType.EVERY_MINUTE
|
||||
),
|
||||
)
|
||||
val ret = executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.CONFIGURE_ALERTS),
|
||||
command = omnipodManager.programAlerts(alerts).ignoreElements(),
|
||||
).toPumpEnactResult()
|
||||
if (ret.success && ret.enacted) {
|
||||
podStateManager.suspendAlertsEnabled = false
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun suspendDelivery(): PumpEnactResult {
|
||||
return executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
|
||||
|
@ -1249,7 +1289,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
expiryAlertDelay.toMinutes().toShort()
|
||||
),
|
||||
BeepType.FOUR_TIMES_BIP_BEEP,
|
||||
BeepRepetitionType.XXX2
|
||||
BeepRepetitionType.EVERY_MINUTE
|
||||
)
|
||||
)
|
||||
return executeProgrammingCommand(
|
||||
|
@ -1369,9 +1409,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
)
|
||||
podStateManager.tempBasal = null
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED))
|
||||
rxBus.send(EventDismissNotification(Notification.FAILED_UPDATE_PROFILE))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TIME_OUT_OF_SYNC))
|
||||
commandQueue.customCommand(CommandDisableSuspendAlerts(), null)
|
||||
}
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TIME_OUT_OF_SYNC))
|
||||
}
|
||||
|
||||
OmnipodCommandType.SET_BASAL_PROFILE -> {
|
||||
|
@ -1394,6 +1436,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
rxBus.send(EventDismissNotification(Notification.FAILED_UPDATE_PROFILE))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TIME_OUT_OF_SYNC))
|
||||
commandQueue.customCommand(CommandDisableSuspendAlerts(), null)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ interface OmnipodDashManager {
|
|||
fun setBasalProgram(basalProgram: BasalProgram, hasBasalBeepEnabled: Boolean): Observable<PodEvent>
|
||||
|
||||
fun suspendDelivery(hasBasalBeepEnabled: Boolean): Observable<PodEvent>
|
||||
|
||||
|
||||
fun setTempBasal(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable<PodEvent>
|
||||
|
||||
fun stopTempBasal(hasTempBasalBeepEnabled: Boolean): Observable<PodEvent>
|
||||
|
|
|
@ -437,7 +437,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
userExpiryAlertDelay.toMinutes().toShort()
|
||||
),
|
||||
BeepType.FOUR_TIMES_BIP_BEEP,
|
||||
BeepRepetitionType.XXX2
|
||||
BeepRepetitionType.EVERY_MINUTE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -498,12 +498,34 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override fun suspendDelivery(hasBasalBeepEnabled: Boolean): Observable<PodEvent> {
|
||||
return Observable.concat(
|
||||
observePodRunning,
|
||||
observeConnectToPod,
|
||||
observeSendStopDeliveryCommand(StopDeliveryCommand.DeliveryType.ALL, hasBasalBeepEnabled)
|
||||
).interceptPodEvents()
|
||||
observeSuspendDeliveryCommand(hasBasalBeepEnabled)
|
||||
).doOnComplete {
|
||||
podStateManager.suspendAlertsEnabled = true
|
||||
}.interceptPodEvents()
|
||||
}
|
||||
|
||||
private fun observeSuspendDeliveryCommand(hasBasalBeepEnabled: Boolean): Observable<PodEvent> {
|
||||
return Observable.defer {
|
||||
val beepType = if (!hasBasalBeepEnabled)
|
||||
BeepType.SILENT
|
||||
else
|
||||
BeepType.LONG_SINGLE_BEEP
|
||||
|
||||
bleManager.sendCommand(
|
||||
SuspendDeliveryCommand.Builder()
|
||||
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
||||
.setUniqueId(podStateManager.uniqueId!!.toInt())
|
||||
.setNonce(NONCE)
|
||||
.setBeepType(beepType)
|
||||
.build(),
|
||||
DefaultStatusResponse::class
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeSendProgramTempBasalCommand(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable<PodEvent> {
|
||||
|
|
|
@ -38,6 +38,18 @@ class ProgramAlertsCommand private constructor(
|
|||
return appendCrc(byteBuffer.array())
|
||||
}
|
||||
|
||||
val encodedWithoutHeaderAndCRC32: ByteArray
|
||||
get() {
|
||||
val byteBuffer: ByteBuffer = ByteBuffer.allocate(getLength().toInt())
|
||||
.put(commandType.value)
|
||||
.put(getBodyLength())
|
||||
.putInt(nonce)
|
||||
for (configuration in alertConfigurations) {
|
||||
byteBuffer.put(configuration.encoded)
|
||||
}
|
||||
return byteBuffer.array()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ProgramAlertsCommand{" +
|
||||
"alertConfigurations=" + alertConfigurations +
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.*
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
|
||||
// StopDelivery.ALL followed by ProgramAlerts
|
||||
class SuspendDeliveryCommand private constructor(
|
||||
uniqueId: Int,
|
||||
sequenceNumber: Short,
|
||||
multiCommandFlag: Boolean,
|
||||
private val beepType: BeepType,
|
||||
nonce: Int
|
||||
) : NonceEnabledCommand(CommandType.STOP_DELIVERY, uniqueId, sequenceNumber, multiCommandFlag, nonce) {
|
||||
|
||||
override val encoded: ByteArray
|
||||
get() {
|
||||
val alerts = listOf(
|
||||
AlertConfiguration(
|
||||
AlertType.SUSPEND_IN_PROGRESS,
|
||||
enabled = true,
|
||||
durationInMinutes = 10,
|
||||
autoOff = false,
|
||||
AlertTrigger.TimerTrigger(
|
||||
1
|
||||
),
|
||||
BeepType.XXX,
|
||||
BeepRepetitionType.XXX4
|
||||
),
|
||||
AlertConfiguration(
|
||||
AlertType.SUSPEND_ENDED,
|
||||
enabled = true,
|
||||
durationInMinutes = 0,
|
||||
autoOff = false,
|
||||
AlertTrigger.TimerTrigger(
|
||||
10
|
||||
),
|
||||
BeepType.FOUR_TIMES_BIP_BEEP,
|
||||
BeepRepetitionType.EVERY_MINUTE
|
||||
),
|
||||
)
|
||||
val programAlerts = ProgramAlertsCommand.Builder()
|
||||
.setNonce(nonce)
|
||||
.setUniqueId(uniqueId)
|
||||
.setAlertConfigurations(alerts)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setMultiCommandFlag(false)
|
||||
.build()
|
||||
.encodedWithoutHeaderAndCRC32
|
||||
|
||||
val byteBuffer = ByteBuffer.allocate(LENGTH + HEADER_LENGTH + programAlerts.size)
|
||||
.put(encodeHeader(uniqueId, sequenceNumber, (LENGTH + programAlerts.size).toShort(), multiCommandFlag))
|
||||
.put(commandType.value)
|
||||
.put(BODY_LENGTH)
|
||||
.putInt(nonce)
|
||||
.put((beepType.value.toInt() shl 4 or DeliveryType.ALL.encoded[0].toInt()).toByte())
|
||||
.put(programAlerts)
|
||||
.array()
|
||||
|
||||
return appendCrc(
|
||||
byteBuffer
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "SuspendDeliveryCommand{" +
|
||||
"deliveryType=" + DeliveryType.ALL +
|
||||
", beepType=" + beepType +
|
||||
", nonce=" + nonce +
|
||||
", commandType=" + commandType +
|
||||
", uniqueId=" + uniqueId +
|
||||
", sequenceNumber=" + sequenceNumber +
|
||||
", multiCommandFlag=" + multiCommandFlag +
|
||||
'}'
|
||||
}
|
||||
|
||||
enum class DeliveryType(
|
||||
private val basal: Boolean,
|
||||
private val tempBasal: Boolean,
|
||||
private val bolus: Boolean
|
||||
) : Encodable {
|
||||
|
||||
BASAL(true, false, false), TEMP_BASAL(false, true, false), BOLUS(false, false, true), ALL(true, true, true);
|
||||
|
||||
override val encoded: ByteArray
|
||||
get() {
|
||||
val bitSet = BitSet(8)
|
||||
bitSet[0] = basal
|
||||
bitSet[1] = tempBasal
|
||||
bitSet[2] = bolus
|
||||
return bitSet.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
class Builder : NonceEnabledCommandBuilder<Builder, SuspendDeliveryCommand>() {
|
||||
private var beepType: BeepType? = BeepType.LONG_SINGLE_BEEP
|
||||
|
||||
fun setBeepType(beepType: BeepType): Builder {
|
||||
this.beepType = beepType
|
||||
return this
|
||||
}
|
||||
|
||||
override fun buildCommand(): SuspendDeliveryCommand {
|
||||
requireNotNull(beepType) { "beepType can not be null" }
|
||||
|
||||
return SuspendDeliveryCommand(
|
||||
uniqueId!!,
|
||||
sequenceNumber!!,
|
||||
multiCommandFlag,
|
||||
beepType!!,
|
||||
nonce!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val LENGTH: Short = 7
|
||||
private const val BODY_LENGTH: Byte = 5
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,8 @@ enum class BeepRepetitionType(
|
|||
) {
|
||||
|
||||
XXX(0x01.toByte()), // Used in lump of coal alert, LOW_RESERVOIR
|
||||
XXX2(0x03.toByte()), // Used in USER_SET_EXPIRATION
|
||||
EVERY_MINUTE(0x03.toByte()), // Used in USER_SET_EXPIRATION, suspend delivery
|
||||
XXX3(0x05.toByte()), // published system expiration alert
|
||||
XXX4(0x06.toByte()), // Used in imminent pod expiration alert, suspend in progress
|
||||
XXX4(0x06.toByte()), // Used in imminent pod expiration alert, suspend in progress. No repeat?
|
||||
XXX5(0x08.toByte()); // Lump of coal alert
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ interface OmnipodDashPodStateManager {
|
|||
var basalProgram: BasalProgram?
|
||||
val activeCommand: ActiveCommand?
|
||||
val lastBolus: LastBolus?
|
||||
var suspendAlertsEnabled: Boolean
|
||||
|
||||
fun increaseMessageSequenceNumber()
|
||||
fun increaseEapAkaSequenceNumber(): ByteArray
|
||||
|
|
|
@ -224,6 +224,13 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
store()
|
||||
}
|
||||
|
||||
override var suspendAlertsEnabled: Boolean
|
||||
get() = podState.suspendAlertsEnabled
|
||||
set(enabled) {
|
||||
podState.suspendAlertsEnabled = enabled
|
||||
store()
|
||||
}
|
||||
|
||||
override val lastStatusResponseReceived: Long
|
||||
get() = podState.lastStatusResponseReceived
|
||||
|
||||
|
@ -713,6 +720,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
var timeZoneOffset: Int? = null
|
||||
var timeZoneUpdated: Long? = null
|
||||
var alarmSynced: Boolean = false
|
||||
var suspendAlertsEnabled: Boolean = false
|
||||
|
||||
var bleVersion: SoftwareVersion? = null
|
||||
var firmwareVersion: SoftwareVersion? = null
|
||||
|
|
|
@ -439,6 +439,10 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
R.string.omnipod_common_alert_expiration_advisory
|
||||
AlertType.AUTO_OFF ->
|
||||
R.string.omnipod_common_alert_shutdown_imminent
|
||||
AlertType.SUSPEND_IN_PROGRESS ->
|
||||
R.string.omnipod_common_alert_delivery_suspended
|
||||
AlertType.SUSPEND_ENDED ->
|
||||
R.string.omnipod_common_alert_delivery_suspended2
|
||||
else ->
|
||||
R.string.omnipod_common_alert_unknown_alert
|
||||
}
|
||||
|
|
|
@ -47,4 +47,6 @@
|
|||
<string name="omnipod_common_history_tbr_value">Rate: %1$.2f U, duration: %2$d minutes</string>
|
||||
<string name="omnipod_common_history_bolus_value">%1$.2f U</string>
|
||||
<string name="dash_bolusdelivering">Delivering %1$.2f U</string>
|
||||
<string name="omnipod_common_alert_delivery_suspended">Insulin delivery is suspended</string>
|
||||
<string name="omnipod_common_alert_delivery_suspended2">Insulin delivery is suspended 2</string>
|
||||
</resources>
|
||||
|
|
|
@ -85,7 +85,7 @@ class ProgramAlertsCommandTest {
|
|||
false,
|
||||
AlertTrigger.TimerTrigger(4079.toShort()),
|
||||
BeepType.FOUR_TIMES_BIP_BEEP,
|
||||
BeepRepetitionType.XXX2
|
||||
BeepRepetitionType.EVERY_MINUTE
|
||||
)
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue