WIP on implementing OmnipodDashPumpPlugin + some autoformatting
This commit is contained in:
parent
811f136830
commit
fe9c5d00a7
18 changed files with 469 additions and 86 deletions
|
@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand;
|
||||
|
||||
public final class CommandAcknowledgeAlerts implements CustomCommand {
|
||||
public final class CommandSilenceAlerts implements CustomCommand {
|
||||
@NotNull @Override public String getStatusDescription() {
|
||||
return "ACKNOWLEDGE ALERTS";
|
||||
}
|
|
@ -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.CustomActionType
|
||||
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.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.ui.OmnipodDashOverviewFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
|
||||
import info.nightscout.androidaps.queue.commands.CustomCommand
|
||||
import info.nightscout.androidaps.utils.TimeChangeType
|
||||
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 java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -25,6 +35,8 @@ import javax.inject.Singleton
|
|||
class OmnipodDashPumpPlugin @Inject constructor(
|
||||
private val omnipodManager: OmnipodDashManager,
|
||||
private val podStateManager: OmnipodDashPodStateManager,
|
||||
private val sp: SP,
|
||||
private val profileFunction: ProfileFunction,
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
resourceHelper: ResourceHelper,
|
||||
|
@ -51,19 +63,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun isSuspended(): Boolean {
|
||||
// TODO
|
||||
return false
|
||||
return podStateManager.isSuspended
|
||||
}
|
||||
|
||||
override fun isBusy(): Boolean {
|
||||
// prevents the queue from executing commands
|
||||
// TODO
|
||||
return true
|
||||
return podStateManager.activationProgress.isBefore(ActivationProgress.COMPLETED)
|
||||
}
|
||||
|
||||
override fun isConnected(): Boolean {
|
||||
// TODO
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun isConnecting(): Boolean {
|
||||
|
@ -93,40 +103,136 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
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 {
|
||||
// TODO
|
||||
return PumpEnactResult(injector).success(true).enacted(true)
|
||||
// TODO history
|
||||
|
||||
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 {
|
||||
// TODO
|
||||
if (podStateManager.basalProgram == null) {
|
||||
// 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 {
|
||||
// TODO
|
||||
return System.currentTimeMillis()
|
||||
return podStateManager.lastConnection
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
// Omnipod Dash doesn't report it's battery level. We return 0 here and hide related fields in the UI
|
||||
get() = 0
|
||||
|
||||
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||
// TODO
|
||||
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO")
|
||||
// TODO history
|
||||
// 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() {
|
||||
// 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(
|
||||
|
@ -135,8 +241,33 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
profile: Profile,
|
||||
enforceNew: Boolean
|
||||
): PumpEnactResult {
|
||||
// TODO
|
||||
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO")
|
||||
// TODO history
|
||||
// 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(
|
||||
|
@ -157,8 +288,29 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
||||
// TODO
|
||||
return PumpEnactResult(injector).success(false).enacted(false).comment("TODO")
|
||||
// TODO history
|
||||
// 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 {
|
||||
|
@ -183,8 +335,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun serialNumber(): String {
|
||||
// TODO
|
||||
return "TODO"
|
||||
return if (podStateManager.uniqueId == null) {
|
||||
"n/a" // TODO i18n
|
||||
} else {
|
||||
podStateManager.uniqueId.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun shortStatus(veryShort: Boolean): String {
|
||||
|
@ -214,11 +369,190 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
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
|
||||
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) {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ interface OmnipodDashManager {
|
|||
|
||||
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 cancelBolus(): Observable<PodEvent>
|
||||
fun stopBolus(): Observable<PodEvent>
|
||||
|
||||
fun playBeep(beepType: BeepType): Observable<PodEvent>
|
||||
|
||||
|
|
|
@ -170,6 +170,8 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
.build(),
|
||||
DefaultStatusResponse::class
|
||||
)
|
||||
}.doOnComplete {
|
||||
podStateManager.basalProgram = basalProgram
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +485,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
.subscribeOn(aapsSchedulers.io)
|
||||
}
|
||||
|
||||
override fun cancelTempBasal(): Observable<PodEvent> {
|
||||
override fun stopTempBasal(): Observable<PodEvent> {
|
||||
return Observable.concat(
|
||||
observePodRunning,
|
||||
observeConnectToPod,
|
||||
|
@ -512,7 +514,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
.subscribeOn(aapsSchedulers.io)
|
||||
}
|
||||
|
||||
override fun cancelBolus(): Observable<PodEvent> {
|
||||
override fun stopBolus(): Observable<PodEvent> {
|
||||
return Observable.concat(
|
||||
observePodRunning,
|
||||
observeConnectToPod,
|
||||
|
|
|
@ -46,11 +46,13 @@ data class Id(val address: ByteArray) {
|
|||
|
||||
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 {
|
||||
return Id(ByteBuffer.allocate(4).putInt(v).array())
|
||||
}
|
||||
|
||||
fun fromLong(v: Long): Id {
|
||||
return Id(ByteBuffer.allocate(8).putLong(v).array().copyOfRange(4, 8))
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ class KeyExchange(
|
|||
var pdmPrivate: ByteArray = X25519.generatePrivateKey(),
|
||||
val pdmNonce: ByteArray = ByteArray(NONCE_SIZE)
|
||||
) {
|
||||
|
||||
val pdmPublic = X25519.publicFromPrivate(pdmPrivate)
|
||||
|
||||
var podPublic = ByteArray(PUBLIC_KEY_SIZE)
|
||||
|
|
|
@ -50,7 +50,14 @@ sealed class EapAkaAttribute {
|
|||
EapAkaAttributeType.AT_RAND ->
|
||||
ret.add(EapAkaAttributeRand.parse(tail.copyOfRange(2, EapAkaAttributeRand.SIZE)))
|
||||
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)
|
||||
}
|
||||
|
@ -70,12 +77,14 @@ data class EapAkaAttributeRand(val payload: ByteArray) : EapAkaAttribute() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun parse(payload: ByteArray): EapAkaAttribute {
|
||||
if (payload.size < 2 + 16) {
|
||||
throw MessageIOException("Could not parse RAND attribute: ${payload.toHex()}")
|
||||
}
|
||||
return EapAkaAttributeRand(payload.copyOfRange(2, 2 + 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 {
|
||||
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 {
|
||||
|
@ -145,6 +159,7 @@ data class EapAkaAttributeCustomIV(val payload: ByteArray) : EapAkaAttribute() {
|
|||
}
|
||||
return EapAkaAttributeCustomIV(payload.copyOfRange(2, 2 + 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 {
|
||||
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 {
|
||||
|
|
|
@ -86,7 +86,11 @@ class SessionEstablisher(
|
|||
aapsLogger.debug(LTag.PUMPBTCOMM, "EAP-AKA: got message: $eapMsg")
|
||||
if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) {
|
||||
// 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}")
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ interface OmnipodDashPodStateManager {
|
|||
|
||||
val tempBasal: TempBasal?
|
||||
val tempBasalActive: Boolean
|
||||
val basalProgram: BasalProgram?
|
||||
var basalProgram: BasalProgram?
|
||||
|
||||
fun increaseMessageSequenceNumber()
|
||||
fun increaseEapAkaSequenceNumber(): ByteArray
|
||||
|
|
|
@ -35,8 +35,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
|
||||
override var activationProgress: ActivationProgress
|
||||
get() = podState.activationProgress
|
||||
set(value) {
|
||||
podState.activationProgress = value
|
||||
set(activationProgress) {
|
||||
podState.activationProgress = activationProgress
|
||||
store()
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
|
||||
override var lastConnection: Long
|
||||
get() = podState.lastConnection
|
||||
set(value) {
|
||||
podState.lastConnection = value
|
||||
set(lastConnection) {
|
||||
podState.lastConnection = lastConnection
|
||||
store()
|
||||
}
|
||||
|
||||
|
@ -145,8 +145,12 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
override val tempBasalActive: Boolean
|
||||
get() = tempBasal != null && tempBasal!!.startTime + tempBasal!!.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
|
||||
|
||||
override val basalProgram: BasalProgram?
|
||||
override var basalProgram: BasalProgram?
|
||||
get() = podState.basalProgram
|
||||
set(basalProgram) {
|
||||
podState.basalProgram = basalProgram
|
||||
store()
|
||||
}
|
||||
|
||||
override fun increaseMessageSequenceNumber() {
|
||||
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
|
||||
|
@ -155,15 +159,15 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
|
||||
override var eapAkaSequenceNumber: Long
|
||||
get() = podState.eapAkaSequenceNumber
|
||||
set(value) {
|
||||
podState.eapAkaSequenceNumber = value
|
||||
set(eapAkaSequenceNumber) {
|
||||
podState.eapAkaSequenceNumber = eapAkaSequenceNumber
|
||||
store()
|
||||
}
|
||||
|
||||
override var ltk: ByteArray?
|
||||
get() = podState.ltk
|
||||
set(value) {
|
||||
podState.ltk = value
|
||||
set(ltk) {
|
||||
podState.ltk = ltk
|
||||
store()
|
||||
}
|
||||
|
||||
|
@ -183,7 +187,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
podState.deliveryStatus = response.deliveryStatus
|
||||
podState.podStatus = response.podStatus
|
||||
podState.pulsesDelivered = response.totalPulsesDelivered
|
||||
if (response.reservoirPulsesRemaining < 1023) {
|
||||
podState.pulsesRemaining = response.reservoirPulsesRemaining
|
||||
}
|
||||
podState.sequenceNumberOfLastProgrammingCommand = response.sequenceNumberOfLastProgrammingCommand
|
||||
podState.minutesSinceActivation = response.minutesSinceActivation
|
||||
podState.activeAlerts = response.activeAlerts
|
||||
|
|
|
@ -20,6 +20,7 @@ import info.nightscout.androidaps.queue.Callback
|
|||
import info.nightscout.androidaps.queue.events.EventQueueChanged
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
|
@ -73,7 +74,6 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
binding.buttonPlayTestBeep.setOnClickListener {
|
||||
// TODO
|
||||
binding.buttonPlayTestBeep.isEnabled = false
|
||||
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep)
|
||||
|
||||
|
@ -114,7 +114,33 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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.pump.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding
|
||||
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.CommandResumeDelivery
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery
|
||||
|
@ -130,7 +130,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
buttonBinding.buttonSilenceAlerts.setOnClickListener {
|
||||
disablePodActionButtons()
|
||||
commandQueue.customCommand(
|
||||
CommandAcknowledgeAlerts(),
|
||||
CommandSilenceAlerts(),
|
||||
DisplayResultDialogCallback(
|
||||
resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts),
|
||||
false
|
||||
|
@ -486,7 +486,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
|
||||
private fun updateSilenceAlertsButton() {
|
||||
if (isAutomaticallySilenceAlertsEnabled() && podStateManager.isPodRunning && (podStateManager.activeAlerts!!.size > 0 || commandQueue.isCustomCommandInQueue(
|
||||
CommandAcknowledgeAlerts::class.java
|
||||
CommandSilenceAlerts::class.java
|
||||
))) {
|
||||
buttonBinding.buttonSilenceAlerts.visibility = View.VISIBLE
|
||||
buttonBinding.buttonSilenceAlerts.isEnabled = isQueueEmpty()
|
||||
|
|
|
@ -3,40 +3,29 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.deactivat
|
|||
import androidx.annotation.StringRes
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
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.queue.command.CommandDeactivatePod
|
||||
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.queue.Callback
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import javax.inject.Inject
|
||||
|
||||
class DashDeactivatePodViewModel @Inject constructor(
|
||||
private val omnipodManager: OmnipodDashManager,
|
||||
private val podStateManager: OmnipodDashPodStateManager,
|
||||
private val commandQueueProvider: CommandQueueProvider,
|
||||
injector: HasAndroidInjector,
|
||||
logger: AAPSLogger
|
||||
) : DeactivatePodViewModel(injector, logger) {
|
||||
|
||||
override fun doExecuteAction(): Single<PumpEnactResult> = Single.create { source ->
|
||||
omnipodManager.deactivatePod().subscribeBy(
|
||||
onNext = { podEvent ->
|
||||
logger.debug(
|
||||
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))
|
||||
commandQueueProvider.customCommand(CommandDeactivatePod(), object : Callback() {
|
||||
override fun run() {
|
||||
source.onSuccess(result)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
override fun discardPod() {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_eros_pod_management_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
|
@ -119,8 +118,7 @@
|
|||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<!-- FIXME visible for development -->
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/button_discard_pod"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
|
@ -128,7 +126,7 @@
|
|||
android:drawableTop="@drawable/ic_pod_management_discard_pod"
|
||||
android:text="@string/omnipod_common_pod_management_button_discard_pod"
|
||||
android:textAllCaps="false"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constrainedHeight="@+id/Actions_Row_2_horizontal_guideline"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toRightOf="@+id/Actions_Col_1_Row_2_vertical_guideline"
|
||||
|
|
|
@ -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.utils.DateTimeUtil;
|
||||
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.CommandHandleTimeChange;
|
||||
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() &&
|
||||
podStateManager.getActiveAlerts().size() > 0 && !getCommandQueue().isCustomCommandInQueue(CommandAcknowledgeAlerts.class)) {
|
||||
podStateManager.getActiveAlerts().size() > 0 && !getCommandQueue().isCustomCommandInQueue(CommandSilenceAlerts.class)) {
|
||||
queueAcknowledgeAlertsCommand();
|
||||
}
|
||||
} else {
|
||||
|
@ -410,7 +410,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
|
|||
rxBus.send(new EventNewNotification(notification));
|
||||
nsUpload.uploadError(notificationText);
|
||||
|
||||
if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && !getCommandQueue().isCustomCommandInQueue(CommandAcknowledgeAlerts.class)) {
|
||||
if (aapsOmnipodErosManager.isAutomaticallyAcknowledgeAlertsEnabled() && !getCommandQueue().isCustomCommandInQueue(CommandSilenceAlerts.class)) {
|
||||
queueAcknowledgeAlertsCommand();
|
||||
}
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
|
|||
}
|
||||
|
||||
private void queueAcknowledgeAlertsCommand() {
|
||||
getCommandQueue().customCommand(new CommandAcknowledgeAlerts(), new Callback() {
|
||||
getCommandQueue().customCommand(new CommandSilenceAlerts(), new Callback() {
|
||||
@Override public void run() {
|
||||
if (result != null) {
|
||||
aapsLogger.debug(LTag.PUMP, "Acknowledge alerts result: {} ({})", result.success, result.comment);
|
||||
|
@ -827,7 +827,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa
|
|||
|
||||
@Override
|
||||
public PumpEnactResult executeCustomCommand(@NonNull CustomCommand command) {
|
||||
if (command instanceof CommandAcknowledgeAlerts) {
|
||||
if (command instanceof CommandSilenceAlerts) {
|
||||
return executeCommand(OmnipodCommandType.ACKNOWLEDGE_ALERTS, aapsOmnipodErosManager::acknowledgeAlerts);
|
||||
}
|
||||
if (command instanceof CommandGetPodStatus) {
|
||||
|
|
|
@ -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.omnipod.common.databinding.OmnipodCommonOverviewButtonsBinding
|
||||
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.CommandResumeDelivery
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandSuspendDelivery
|
||||
|
@ -148,7 +148,8 @@ class OmnipodErosOverviewFragment : DaggerFragment() {
|
|||
|
||||
buttonBinding.buttonSilenceAlerts.setOnClickListener {
|
||||
disablePodActionButtons()
|
||||
commandQueue.customCommand(CommandAcknowledgeAlerts(),
|
||||
commandQueue.customCommand(
|
||||
CommandSilenceAlerts(),
|
||||
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), false)
|
||||
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_silenced_alerts))
|
||||
.actionOnSuccess { rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_ALERTS)) })
|
||||
|
@ -513,7 +514,8 @@ class OmnipodErosOverviewFragment : DaggerFragment() {
|
|||
}
|
||||
|
||||
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.isEnabled = rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
|
||||
} else {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_eros_pod_management_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
|
@ -125,7 +124,7 @@
|
|||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/button_play_test_beep"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
|
@ -256,7 +255,7 @@
|
|||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/button_pulse_log"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
|
|
Loading…
Reference in a new issue