WIP on implementing OmnipodDashPumpPlugin + some autoformatting

This commit is contained in:
Bart Sopers 2021-03-31 11:18:58 +02:00
parent 811f136830
commit fe9c5d00a7
18 changed files with 469 additions and 86 deletions

View file

@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull;
import info.nightscout.androidaps.queue.commands.CustomCommand; import info.nightscout.androidaps.queue.commands.CustomCommand;
public final class CommandAcknowledgeAlerts implements CustomCommand { public final class CommandSilenceAlerts implements CustomCommand {
@NotNull @Override public String getStatusDescription() { @NotNull @Override public String getStatusDescription() {
return "ACKNOWLEDGE ALERTS"; return "ACKNOWLEDGE ALERTS";
} }

View file

@ -11,13 +11,23 @@ import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.queue.commands.CustomCommand
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Single
import io.reactivex.rxkotlin.blockingSubscribeBy
import io.reactivex.rxkotlin.subscribeBy
import org.json.JSONObject import org.json.JSONObject
import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -25,6 +35,8 @@ import javax.inject.Singleton
class OmnipodDashPumpPlugin @Inject constructor( class OmnipodDashPumpPlugin @Inject constructor(
private val omnipodManager: OmnipodDashManager, private val omnipodManager: OmnipodDashManager,
private val podStateManager: OmnipodDashPodStateManager, private val podStateManager: OmnipodDashPodStateManager,
private val sp: SP,
private val profileFunction: ProfileFunction,
injector: HasAndroidInjector, injector: HasAndroidInjector,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
@ -51,19 +63,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun isSuspended(): Boolean { override fun isSuspended(): Boolean {
// TODO return podStateManager.isSuspended
return false
} }
override fun isBusy(): Boolean { override fun isBusy(): Boolean {
// prevents the queue from executing commands // prevents the queue from executing commands
// TODO return podStateManager.activationProgress.isBefore(ActivationProgress.COMPLETED)
return true
} }
override fun isConnected(): Boolean { override fun isConnected(): Boolean {
// TODO // TODO
return false return true
} }
override fun isConnecting(): Boolean { override fun isConnecting(): Boolean {
@ -93,40 +103,136 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun getPumpStatus(reason: String) { override fun getPumpStatus(reason: String) {
// TODO // TODO history
omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE).blockingSubscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in getPumpStatus: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable)
},
onComplete = {
aapsLogger.debug("getPumpStatus completed")
}
)
} }
override fun setNewBasalProfile(profile: Profile): PumpEnactResult { override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
// TODO // TODO history
return PumpEnactResult(injector).success(true).enacted(true)
return Single.create<PumpEnactResult> { source ->
omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in setNewBasalProfile: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in setNewBasalProfile", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("setNewBasalProfile completed")
source.onSuccess(PumpEnactResult(injector).success(true).enacted(true))
}
)
}.blockingGet()
} }
override fun isThisProfileSet(profile: Profile): Boolean { override fun isThisProfileSet(profile: Profile): Boolean {
// TODO if (podStateManager.basalProgram == null) {
return true // We don't have an active Pod. Return true here because the next Pod will use the currently active profile
return true
}
return podStateManager.basalProgram!! == mapProfileToBasalProgram(profile)
} }
override fun lastDataTime(): Long { override fun lastDataTime(): Long {
// TODO return podStateManager.lastConnection
return System.currentTimeMillis()
} }
override val baseBasalRate: Double override val baseBasalRate: Double
get() = 0.0 // TODO get() {
if (podStateManager.basalProgram == null) {
return 0.0
}
return podStateManager.basalProgram!!.rateAt(Date())
}
override val reservoirLevel: Double override val reservoirLevel: Double
get() = 0.0 // TODO get() {
if (podStateManager.activationProgress.isBefore(ActivationProgress.COMPLETED)) {
return 0.0
}
// Omnipod only reports reservoir level when there's < 1023 pulses left
return podStateManager.pulsesRemaining?.let {
it * 0.05
} ?: 75.0
}
override val batteryLevel: Int override val batteryLevel: Int
// Omnipod Dash doesn't report it's battery level. We return 0 here and hide related fields in the UI
get() = 0 get() = 0
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult { override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
// TODO // TODO history
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO") // TODO update Treatments (?)
// TODO bolus progress
// TODO report actual delivered amount after Pod Alarm and bolus cancellation
return Single.create<PumpEnactResult> { source ->
val bolusBeeps = sp.getBoolean(R.string.key_omnipod_common_bolus_beeps_enabled, false)
omnipodManager.bolus(
detailedBolusInfo.insulin,
bolusBeeps,
bolusBeeps
).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in deliverTreatment: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("deliverTreatment completed")
source.onSuccess(
PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin)
.carbsDelivered(detailedBolusInfo.carbs)
)
}
)
}.blockingGet()
} }
override fun stopBolusDelivering() { override fun stopBolusDelivering() {
// TODO // TODO history
// TODO update Treatments (?)
omnipodManager.stopBolus().blockingSubscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in stopBolusDelivering: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in stopBolusDelivering", throwable)
},
onComplete = {
aapsLogger.debug("stopBolusDelivering completed")
}
)
} }
override fun setTempBasalAbsolute( override fun setTempBasalAbsolute(
@ -135,8 +241,33 @@ class OmnipodDashPumpPlugin @Inject constructor(
profile: Profile, profile: Profile,
enforceNew: Boolean enforceNew: Boolean
): PumpEnactResult { ): PumpEnactResult {
// TODO // TODO history
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO") // TODO update Treatments
return Single.create<PumpEnactResult> { source ->
omnipodManager.setTempBasal(
absoluteRate,
durationInMinutes.toShort()
).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in setTempBasalAbsolute: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in setTempBasalAbsolute", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("setTempBasalAbsolute completed")
source.onSuccess(
PumpEnactResult(injector).success(true).enacted(true).absolute(absoluteRate)
.duration(durationInMinutes)
)
}
)
}.blockingGet()
} }
override fun setTempBasalPercent( override fun setTempBasalPercent(
@ -157,8 +288,29 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
// TODO // TODO history
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO") // TODO update Treatments
return Single.create<PumpEnactResult> { source ->
omnipodManager.stopTempBasal().subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in cancelTempBasal: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in cancelTempBasal", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("cancelTempBasal completed")
source.onSuccess(
PumpEnactResult(injector).success(true).enacted(true)
)
}
)
}.blockingGet()
} }
override fun cancelExtendedBolus(): PumpEnactResult { override fun cancelExtendedBolus(): PumpEnactResult {
@ -183,8 +335,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun serialNumber(): String { override fun serialNumber(): String {
// TODO return if (podStateManager.uniqueId == null) {
return "TODO" "n/a" // TODO i18n
} else {
podStateManager.uniqueId.toString()
}
} }
override fun shortStatus(veryShort: Boolean): String { override fun shortStatus(veryShort: Boolean): String {
@ -214,11 +369,190 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? { override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? {
if (customCommand is CommandSilenceAlerts) {
return silenceAlerts()
}
if (customCommand is CommandSuspendDelivery) {
return suspendDelivery()
}
if (customCommand is CommandResumeDelivery) {
return resumeDelivery()
}
if (customCommand is CommandDeactivatePod) {
return deactivatePod()
}
if (customCommand is CommandHandleTimeChange) {
return handleTimeChange()
}
if (customCommand is CommandUpdateAlertConfiguration) {
return updateAlertConfiguration()
}
if (customCommand is CommandPlayTestBeep) {
return playTestBeep()
}
aapsLogger.warn(LTag.PUMP, "Unsupported custom command: " + customCommand.javaClass.name)
return PumpEnactResult(injector).success(false).enacted(false).comment(
resourceHelper.gs(
R.string.omnipod_common_error_unsupported_custom_command,
customCommand.javaClass.name
)
)
}
private fun silenceAlerts(): PumpEnactResult {
// TODO history
// TODO filter alert types
return podStateManager.activeAlerts?.let {
Single.create<PumpEnactResult> { source ->
omnipodManager.silenceAlerts(it).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in silenceAlerts: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in silenceAlerts", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("silenceAlerts completed")
source.onSuccess(PumpEnactResult(injector).success(true))
}
)
}.blockingGet()
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No active alerts") // TODO i18n
}
private fun suspendDelivery(): PumpEnactResult {
// TODO history
return Single.create<PumpEnactResult> { source ->
omnipodManager.suspendDelivery().subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in suspendDelivery: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in suspendDelivery", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("suspendDelivery completed")
source.onSuccess(PumpEnactResult(injector).success(true))
}
)
}.blockingGet()
}
private fun resumeDelivery(): PumpEnactResult {
// TODO history
return profileFunction.getProfile()?.let {
Single.create<PumpEnactResult> { source ->
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in resumeDelivery: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in resumeDelivery", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("resumeDelivery completed")
source.onSuccess(PumpEnactResult(injector).success(true))
}
)
}.blockingGet()
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n
}
private fun deactivatePod(): PumpEnactResult {
// TODO history
return Single.create<PumpEnactResult> { source ->
omnipodManager.deactivatePod().subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in deactivatePod: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in deactivatePod", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("deactivatePod completed")
source.onSuccess(PumpEnactResult(injector).success(true))
}
)
}.blockingGet()
}
private fun handleTimeChange(): PumpEnactResult {
// TODO // TODO
return null return PumpEnactResult(injector).success(false).enacted(false).comment("NOT IMPLEMENTED")
}
private fun updateAlertConfiguration(): PumpEnactResult {
// TODO
return PumpEnactResult(injector).success(false).enacted(false).comment("NOT IMPLEMENTED")
}
private fun playTestBeep(): PumpEnactResult {
// TODO history
return Single.create<PumpEnactResult> { source ->
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).subscribeBy(
onNext = { podEvent ->
aapsLogger.debug(
LTag.PUMP,
"Received PodEvent in playTestBeep: $podEvent"
)
},
onError = { throwable ->
aapsLogger.error(LTag.PUMP, "Error in playTestBeep", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message))
},
onComplete = {
aapsLogger.debug("playTestBeep completed")
source.onSuccess(
PumpEnactResult(injector).success(true).enacted(true)
)
}
)
}.blockingGet()
} }
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) { override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {
// TODO val eventHandlingEnabled = sp.getBoolean(R.string.key_omnipod_common_time_change_event_enabled, false)
aapsLogger.info(
LTag.PUMP,
"Time, Date and/or TimeZone changed. [timeChangeType=" + timeChangeType.name + ", eventHandlingEnabled=" + eventHandlingEnabled + "]"
)
if (timeChangeType == TimeChangeType.TimeChanged) {
aapsLogger.info(LTag.PUMP, "Ignoring time change because it is not a DST or TZ change")
return
} else if (!podStateManager.isPodRunning) {
aapsLogger.info(LTag.PUMP, "Ignoring time change because no Pod is active")
return
}
aapsLogger.info(LTag.PUMP, "Handling time change")
commandQueue.customCommand(CommandHandleTimeChange(false), null)
} }
} }

View file

@ -26,11 +26,11 @@ interface OmnipodDashManager {
fun setTempBasal(rate: Double, durationInMinutes: Short): Observable<PodEvent> fun setTempBasal(rate: Double, durationInMinutes: Short): Observable<PodEvent>
fun cancelTempBasal(): Observable<PodEvent> fun stopTempBasal(): Observable<PodEvent>
fun bolus(units: Double, confirmationBeeps: Boolean, completionBeeps: Boolean): Observable<PodEvent> fun bolus(units: Double, confirmationBeeps: Boolean, completionBeeps: Boolean): Observable<PodEvent>
fun cancelBolus(): Observable<PodEvent> fun stopBolus(): Observable<PodEvent>
fun playBeep(beepType: BeepType): Observable<PodEvent> fun playBeep(beepType: BeepType): Observable<PodEvent>

View file

@ -170,6 +170,8 @@ class OmnipodDashManagerImpl @Inject constructor(
.build(), .build(),
DefaultStatusResponse::class DefaultStatusResponse::class
) )
}.doOnComplete {
podStateManager.basalProgram = basalProgram
} }
} }
@ -483,7 +485,7 @@ class OmnipodDashManagerImpl @Inject constructor(
.subscribeOn(aapsSchedulers.io) .subscribeOn(aapsSchedulers.io)
} }
override fun cancelTempBasal(): Observable<PodEvent> { override fun stopTempBasal(): Observable<PodEvent> {
return Observable.concat( return Observable.concat(
observePodRunning, observePodRunning,
observeConnectToPod, observeConnectToPod,
@ -512,7 +514,7 @@ class OmnipodDashManagerImpl @Inject constructor(
.subscribeOn(aapsSchedulers.io) .subscribeOn(aapsSchedulers.io)
} }
override fun cancelBolus(): Observable<PodEvent> { override fun stopBolus(): Observable<PodEvent> {
return Observable.concat( return Observable.concat(
observePodRunning, observePodRunning,
observeConnectToPod, observeConnectToPod,

View file

@ -46,11 +46,13 @@ data class Id(val address: ByteArray) {
companion object { companion object {
private const val PERIPHERAL_NODE_INDEX = 1 // TODO: understand the meaning of this value. It comes from preferences private const val PERIPHERAL_NODE_INDEX =
1 // TODO: understand the meaning of this value. It comes from preferences
fun fromInt(v: Int): Id { fun fromInt(v: Int): Id {
return Id(ByteBuffer.allocate(4).putInt(v).array()) return Id(ByteBuffer.allocate(4).putInt(v).array())
} }
fun fromLong(v: Long): Id { fun fromLong(v: Long): Id {
return Id(ByteBuffer.allocate(8).putLong(v).array().copyOfRange(4, 8)) return Id(ByteBuffer.allocate(8).putLong(v).array().copyOfRange(4, 8))
} }

View file

@ -16,6 +16,7 @@ class KeyExchange(
var pdmPrivate: ByteArray = X25519.generatePrivateKey(), var pdmPrivate: ByteArray = X25519.generatePrivateKey(),
val pdmNonce: ByteArray = ByteArray(NONCE_SIZE) val pdmNonce: ByteArray = ByteArray(NONCE_SIZE)
) { ) {
val pdmPublic = X25519.publicFromPrivate(pdmPrivate) val pdmPublic = X25519.publicFromPrivate(pdmPrivate)
var podPublic = ByteArray(PUBLIC_KEY_SIZE) var podPublic = ByteArray(PUBLIC_KEY_SIZE)

View file

@ -50,7 +50,14 @@ sealed class EapAkaAttribute {
EapAkaAttributeType.AT_RAND -> EapAkaAttributeType.AT_RAND ->
ret.add(EapAkaAttributeRand.parse(tail.copyOfRange(2, EapAkaAttributeRand.SIZE))) ret.add(EapAkaAttributeRand.parse(tail.copyOfRange(2, EapAkaAttributeRand.SIZE)))
EapAkaAttributeType.AT_CLIENT_ERROR_CODE -> EapAkaAttributeType.AT_CLIENT_ERROR_CODE ->
ret.add(EapAkaAttributeClientErrorCode.parse(tail.copyOfRange(2, EapAkaAttributeClientErrorCode.SIZE))) ret.add(
EapAkaAttributeClientErrorCode.parse(
tail.copyOfRange(
2,
EapAkaAttributeClientErrorCode.SIZE
)
)
)
} }
tail = tail.copyOfRange(size, tail.size) tail = tail.copyOfRange(size, tail.size)
} }
@ -70,12 +77,14 @@ data class EapAkaAttributeRand(val payload: ByteArray) : EapAkaAttribute() {
} }
companion object { companion object {
fun parse(payload: ByteArray): EapAkaAttribute { fun parse(payload: ByteArray): EapAkaAttribute {
if (payload.size < 2 + 16) { if (payload.size < 2 + 16) {
throw MessageIOException("Could not parse RAND attribute: ${payload.toHex()}") throw MessageIOException("Could not parse RAND attribute: ${payload.toHex()}")
} }
return EapAkaAttributeRand(payload.copyOfRange(2, 2 + 16)) return EapAkaAttributeRand(payload.copyOfRange(2, 2 + 16))
} }
const val SIZE = 20 // type, size, 2 reserved bytes, payload=16 const val SIZE = 20 // type, size, 2 reserved bytes, payload=16
} }
} }
@ -110,7 +119,12 @@ data class EapAkaAttributeRes(val payload: ByteArray) : EapAkaAttribute() {
} }
override fun toByteArray(): ByteArray { override fun toByteArray(): ByteArray {
return byteArrayOf(EapAkaAttributeType.AT_RES.type, (SIZE / SIZE_MULTIPLIER).toByte(), 0, PAYLOAD_SIZE_BITS) + payload return byteArrayOf(
EapAkaAttributeType.AT_RES.type,
(SIZE / SIZE_MULTIPLIER).toByte(),
0,
PAYLOAD_SIZE_BITS
) + payload
} }
companion object { companion object {
@ -145,6 +159,7 @@ data class EapAkaAttributeCustomIV(val payload: ByteArray) : EapAkaAttribute() {
} }
return EapAkaAttributeCustomIV(payload.copyOfRange(2, 2 + 4)) return EapAkaAttributeCustomIV(payload.copyOfRange(2, 2 + 4))
} }
const val SIZE = 8 // type, size, 2 reserved bytes, payload=4 const val SIZE = 8 // type, size, 2 reserved bytes, payload=4
} }
} }
@ -156,7 +171,12 @@ data class EapAkaAttributeClientErrorCode(val payload: ByteArray) : EapAkaAttrib
} }
override fun toByteArray(): ByteArray { override fun toByteArray(): ByteArray {
return byteArrayOf(EapAkaAttributeType.AT_CLIENT_ERROR_CODE.type, (SIZE / SIZE_MULTIPLIER).toByte(), 0, 0) + payload return byteArrayOf(
EapAkaAttributeType.AT_CLIENT_ERROR_CODE.type,
(SIZE / SIZE_MULTIPLIER).toByte(),
0,
0
) + payload
} }
companion object { companion object {

View file

@ -86,7 +86,11 @@ class SessionEstablisher(
aapsLogger.debug(LTag.PUMPBTCOMM, "EAP-AKA: got message: $eapMsg") aapsLogger.debug(LTag.PUMPBTCOMM, "EAP-AKA: got message: $eapMsg")
if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) { if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) {
// TODO: special exception for this // TODO: special exception for this
throw SessionEstablishmentException("Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${eapMsg.attributes[0].toByteArray().toHex()}") throw SessionEstablishmentException(
"Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${
eapMsg.attributes[0].toByteArray().toHex()
}"
)
} }
throw SessionEstablishmentException("Expecting two attributes, got: ${eapMsg.attributes.size}") throw SessionEstablishmentException("Expecting two attributes, got: ${eapMsg.attributes.size}")
} }

View file

@ -13,7 +13,7 @@ class ProgramInsulinCommand internal constructor(
multiCommandFlag: Boolean, multiCommandFlag: Boolean,
nonce: Int, nonce: Int,
insulinProgramElements: insulinProgramElements:
List<ShortInsulinProgramElement>, List<ShortInsulinProgramElement>,
private val checksum: Short, private val checksum: Short,
private val byte9: Byte, private val byte9: Byte,
private val byte10And11: Short, private val byte10And11: Short,

View file

@ -47,7 +47,7 @@ interface OmnipodDashPodStateManager {
val tempBasal: TempBasal? val tempBasal: TempBasal?
val tempBasalActive: Boolean val tempBasalActive: Boolean
val basalProgram: BasalProgram? var basalProgram: BasalProgram?
fun increaseMessageSequenceNumber() fun increaseMessageSequenceNumber()
fun increaseEapAkaSequenceNumber(): ByteArray fun increaseEapAkaSequenceNumber(): ByteArray

View file

@ -35,8 +35,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override var activationProgress: ActivationProgress override var activationProgress: ActivationProgress
get() = podState.activationProgress get() = podState.activationProgress
set(value) { set(activationProgress) {
podState.activationProgress = value podState.activationProgress = activationProgress
store() store()
} }
@ -55,8 +55,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override var lastConnection: Long override var lastConnection: Long
get() = podState.lastConnection get() = podState.lastConnection
set(value) { set(lastConnection) {
podState.lastConnection = value podState.lastConnection = lastConnection
store() store()
} }
@ -145,8 +145,12 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val tempBasalActive: Boolean override val tempBasalActive: Boolean
get() = tempBasal != null && tempBasal!!.startTime + tempBasal!!.durationInMinutes * 60 * 1000 > System.currentTimeMillis() get() = tempBasal != null && tempBasal!!.startTime + tempBasal!!.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
override val basalProgram: BasalProgram? override var basalProgram: BasalProgram?
get() = podState.basalProgram get() = podState.basalProgram
set(basalProgram) {
podState.basalProgram = basalProgram
store()
}
override fun increaseMessageSequenceNumber() { override fun increaseMessageSequenceNumber() {
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort() podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
@ -155,15 +159,15 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override var eapAkaSequenceNumber: Long override var eapAkaSequenceNumber: Long
get() = podState.eapAkaSequenceNumber get() = podState.eapAkaSequenceNumber
set(value) { set(eapAkaSequenceNumber) {
podState.eapAkaSequenceNumber = value podState.eapAkaSequenceNumber = eapAkaSequenceNumber
store() store()
} }
override var ltk: ByteArray? override var ltk: ByteArray?
get() = podState.ltk get() = podState.ltk
set(value) { set(ltk) {
podState.ltk = value podState.ltk = ltk
store() store()
} }
@ -183,7 +187,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
podState.deliveryStatus = response.deliveryStatus podState.deliveryStatus = response.deliveryStatus
podState.podStatus = response.podStatus podState.podStatus = response.podStatus
podState.pulsesDelivered = response.totalPulsesDelivered podState.pulsesDelivered = response.totalPulsesDelivered
podState.pulsesRemaining = response.reservoirPulsesRemaining if (response.reservoirPulsesRemaining < 1023) {
podState.pulsesRemaining = response.reservoirPulsesRemaining
}
podState.sequenceNumberOfLastProgrammingCommand = response.sequenceNumberOfLastProgrammingCommand podState.sequenceNumberOfLastProgrammingCommand = response.sequenceNumberOfLastProgrammingCommand
podState.minutesSinceActivation = response.minutesSinceActivation podState.minutesSinceActivation = response.minutesSinceActivation
podState.activeAlerts = response.activeAlerts podState.activeAlerts = response.activeAlerts

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
@ -73,7 +74,6 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
} }
binding.buttonPlayTestBeep.setOnClickListener { binding.buttonPlayTestBeep.setOnClickListener {
// TODO
binding.buttonPlayTestBeep.isEnabled = false binding.buttonPlayTestBeep.isEnabled = false
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep) binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep)
@ -114,7 +114,33 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
} }
private fun refreshButtons() { private fun refreshButtons() {
// TODO update button state from Pod state // Only show the discard button to reset a cached unique ID before the unique ID has actually been set
// Otherwise, users should use the Deactivate Pod Wizard. In case proper deactivation fails,
// they will get an option to discard the Pod there
val discardButtonEnabled =
podStateManager.uniqueId != null && podStateManager.activationProgress.isBefore(ActivationProgress.SET_UNIQUE_ID)
binding.buttonDiscardPod.visibility = discardButtonEnabled.toVisibility()
binding.buttonActivatePod.isEnabled = podStateManager.activationProgress.isBefore(ActivationProgress.COMPLETED)
binding.buttonDeactivatePod.isEnabled =
podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED)
if (podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED)) {
if (commandQueue.isCustomCommandInQueue(CommandPlayTestBeep::class.java)) {
binding.buttonPlayTestBeep.isEnabled = false
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep)
} else {
binding.buttonPlayTestBeep.isEnabled = true
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_play_test_beep)
}
} else {
binding.buttonPlayTestBeep.isEnabled = false
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_play_test_beep)
}
if (discardButtonEnabled) {
binding.buttonDiscardPod.isEnabled = true
}
} }
private fun displayErrorDialog(title: String, message: String, @Suppress("SameParameterValue") withSound: Boolean) { private fun displayErrorDialog(title: String, message: String, @Suppress("SameParameterValue") withSound: Boolean) {

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewPodInfoBinding import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewPodInfoBinding
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandAcknowledgeAlerts import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSilenceAlerts
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandResumeDelivery import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandResumeDelivery
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery
@ -130,7 +130,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
buttonBinding.buttonSilenceAlerts.setOnClickListener { buttonBinding.buttonSilenceAlerts.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand( commandQueue.customCommand(
CommandAcknowledgeAlerts(), CommandSilenceAlerts(),
DisplayResultDialogCallback( DisplayResultDialogCallback(
resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts),
false false
@ -486,7 +486,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
private fun updateSilenceAlertsButton() { private fun updateSilenceAlertsButton() {
if (isAutomaticallySilenceAlertsEnabled() && podStateManager.isPodRunning && (podStateManager.activeAlerts!!.size > 0 || commandQueue.isCustomCommandInQueue( if (isAutomaticallySilenceAlertsEnabled() && podStateManager.isPodRunning && (podStateManager.activeAlerts!!.size > 0 || commandQueue.isCustomCommandInQueue(
CommandAcknowledgeAlerts::class.java CommandSilenceAlerts::class.java
))) { ))) {
buttonBinding.buttonSilenceAlerts.visibility = View.VISIBLE buttonBinding.buttonSilenceAlerts.visibility = View.VISIBLE
buttonBinding.buttonSilenceAlerts.isEnabled = isQueueEmpty() buttonBinding.buttonSilenceAlerts.isEnabled = isQueueEmpty()

View file

@ -3,40 +3,29 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.deactivat
import androidx.annotation.StringRes import androidx.annotation.StringRes
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.common.R import info.nightscout.androidaps.plugins.pump.omnipod.common.R
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action.DeactivatePodViewModel import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action.DeactivatePodViewModel
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
import info.nightscout.androidaps.queue.Callback
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.rxkotlin.subscribeBy
import javax.inject.Inject import javax.inject.Inject
class DashDeactivatePodViewModel @Inject constructor( class DashDeactivatePodViewModel @Inject constructor(
private val omnipodManager: OmnipodDashManager,
private val podStateManager: OmnipodDashPodStateManager, private val podStateManager: OmnipodDashPodStateManager,
private val commandQueueProvider: CommandQueueProvider,
injector: HasAndroidInjector, injector: HasAndroidInjector,
logger: AAPSLogger logger: AAPSLogger
) : DeactivatePodViewModel(injector, logger) { ) : DeactivatePodViewModel(injector, logger) {
override fun doExecuteAction(): Single<PumpEnactResult> = Single.create { source -> override fun doExecuteAction(): Single<PumpEnactResult> = Single.create { source ->
omnipodManager.deactivatePod().subscribeBy( commandQueueProvider.customCommand(CommandDeactivatePod(), object : Callback() {
onNext = { podEvent -> override fun run() {
logger.debug( source.onSuccess(result)
LTag.PUMP,
"Received PodEvent in Pod deactivation: $podEvent"
)
},
onError = { throwable ->
logger.error(LTag.PUMP, "Error in Pod deactivation", throwable)
source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message))
},
onComplete = {
logger.debug("Pod deactivation completed")
source.onSuccess(PumpEnactResult(injector).success(true))
} }
) })
} }
override fun discardPod() { override fun discardPod() {

View file

@ -14,7 +14,6 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/omnipod_eros_pod_management_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
@ -119,8 +118,7 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" /> app:layout_constraintGuide_percent="0.5" />
<!-- FIXME visible for development --> <androidx.appcompat.widget.AppCompatButton
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/button_discard_pod" android:id="@+id/button_discard_pod"
style="?android:attr/buttonStyle" style="?android:attr/buttonStyle"
android:layout_width="0dp" android:layout_width="0dp"
@ -128,7 +126,7 @@
android:drawableTop="@drawable/ic_pod_management_discard_pod" android:drawableTop="@drawable/ic_pod_management_discard_pod"
android:text="@string/omnipod_common_pod_management_button_discard_pod" android:text="@string/omnipod_common_pod_management_button_discard_pod"
android:textAllCaps="false" android:textAllCaps="false"
android:visibility="visible" android:visibility="gone"
app:layout_constrainedHeight="@+id/Actions_Row_2_horizontal_guideline" app:layout_constrainedHeight="@+id/Actions_Row_2_horizontal_guideline"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@+id/Actions_Col_1_Row_2_vertical_guideline" app:layout_constraintLeft_toRightOf="@+id/Actions_Col_1_Row_2_vertical_guideline"

View file

@ -65,7 +65,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType; import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType;
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandAcknowledgeAlerts; import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSilenceAlerts;
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod; import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod;
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange; import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange;
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandPlayTestBeep; import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandPlayTestBeep;
@ -253,7 +253,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
} }
if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && podStateManager.isPodActivationCompleted() && !podStateManager.isPodDead() && if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && podStateManager.isPodActivationCompleted() && !podStateManager.isPodDead() &&
podStateManager.getActiveAlerts().size() > 0 && !getCommandQueue().isCustomCommandInQueue(CommandAcknowledgeAlerts.class)) { podStateManager.getActiveAlerts().size() > 0 && !getCommandQueue().isCustomCommandInQueue(CommandSilenceAlerts.class)) {
queueAcknowledgeAlertsCommand(); queueAcknowledgeAlertsCommand();
} }
} else { } else {
@ -410,7 +410,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
nsUpload.uploadError(notificationText); nsUpload.uploadError(notificationText);
if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && !getCommandQueue().isCustomCommandInQueue(CommandAcknowledgeAlerts.class)) { if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && !getCommandQueue().isCustomCommandInQueue(CommandSilenceAlerts.class)) {
queueAcknowledgeAlertsCommand(); queueAcknowledgeAlertsCommand();
} }
} }
@ -437,7 +437,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
} }
private void queueAcknowledgeAlertsCommand() { private void queueAcknowledgeAlertsCommand() {
getCommandQueue().customCommand(new CommandAcknowledgeAlerts(), new Callback() { getCommandQueue().customCommand(new CommandSilenceAlerts(), new Callback() {
@Override public void run() { @Override public void run() {
if (result != null) { if (result != null) {
aapsLogger.debug(LTag.PUMP, "Acknowledge alerts result: {} ({})", result.success, result.comment); aapsLogger.debug(LTag.PUMP, "Acknowledge alerts result: {} ({})", result.success, result.comment);
@ -827,7 +827,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
@Override @Override
public PumpEnactResult executeCustomCommand(@NonNull CustomCommand command) { public PumpEnactResult executeCustomCommand(@NonNull CustomCommand command) {
if (command instanceof CommandAcknowledgeAlerts) { if (command instanceof CommandSilenceAlerts) {
return executeCommand(OmnipodCommandType.ACKNOWLEDGE_ALERTS, aapsOmnipodErosManager::acknowledgeAlerts); return executeCommand(OmnipodCommandType.ACKNOWLEDGE_ALERTS, aapsOmnipodErosManager::acknowledgeAlerts);
} }
if (command instanceof CommandGetPodStatus) { if (command instanceof CommandGetPodStatus) {

View file

@ -24,7 +24,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding
import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewPodInfoBinding import info.nightscout.androidaps.plugins.pump.omnipod.common.databinding.OmnipodCommonOverviewPodInfoBinding
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandAcknowledgeAlerts import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSilenceAlerts
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandHandleTimeChange
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandResumeDelivery import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandResumeDelivery
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery
@ -148,7 +148,8 @@ class OmnipodErosOverviewFragment : DaggerFragment() {
buttonBinding.buttonSilenceAlerts.setOnClickListener { buttonBinding.buttonSilenceAlerts.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand(CommandAcknowledgeAlerts(), commandQueue.customCommand(
CommandSilenceAlerts(),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), false) DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), false)
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_silenced_alerts)) .messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_silenced_alerts))
.actionOnSuccess { rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_ALERTS)) }) .actionOnSuccess { rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_ALERTS)) })
@ -513,7 +514,8 @@ class OmnipodErosOverviewFragment : DaggerFragment() {
} }
private fun updateSilenceAlertsButton() { private fun updateSilenceAlertsButton() {
if (!omnipodManager.isAutomaticallyAcknowledgeAlertsEnabled && podStateManager.isPodRunning && (podStateManager.hasActiveAlerts() || commandQueue.isCustomCommandInQueue(CommandAcknowledgeAlerts::class.java))) { if (!omnipodManager.isAutomaticallyAcknowledgeAlertsEnabled && podStateManager.isPodRunning && (podStateManager.hasActiveAlerts() || commandQueue.isCustomCommandInQueue(
CommandSilenceAlerts::class.java))) {
buttonBinding.buttonSilenceAlerts.visibility = View.VISIBLE buttonBinding.buttonSilenceAlerts.visibility = View.VISIBLE
buttonBinding.buttonSilenceAlerts.isEnabled = rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() buttonBinding.buttonSilenceAlerts.isEnabled = rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
} else { } else {

View file

@ -14,7 +14,6 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/omnipod_eros_pod_management_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
@ -125,7 +124,7 @@
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintGuide_percent="0" /> app:layout_constraintGuide_percent="0" />
<info.nightscout.androidaps.utils.ui.SingleClickButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/button_play_test_beep" android:id="@+id/button_play_test_beep"
style="?android:attr/buttonStyle" style="?android:attr/buttonStyle"
android:layout_width="0dp" android:layout_width="0dp"
@ -256,7 +255,7 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" /> app:layout_constraintGuide_percent="0.5" />
<info.nightscout.androidaps.utils.ui.SingleClickButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/button_pulse_log" android:id="@+id/button_pulse_log"
style="?android:attr/buttonStyle" style="?android:attr/buttonStyle"
android:layout_width="0dp" android:layout_width="0dp"