Merge pull request #39 from 0pen-dash/avereha/alarms

Avereha/alarms
This commit is contained in:
Andrei Vereha 2021-06-06 21:30:24 +02:00 committed by GitHub
commit 8b87919b05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 207 additions and 108 deletions

View file

@ -4,6 +4,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -17,7 +18,6 @@ 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.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants
@ -39,12 +39,13 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.rxkotlin.blockingSubscribeBy
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.subscribeBy
import org.json.JSONObject
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.random.Random
@Singleton
class OmnipodDashPumpPlugin @Inject constructor(
@ -55,6 +56,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
private val history: DashHistory,
private val pumpSync: PumpSync,
private val rxBus: RxBusWrapper,
// private val disposable: CompositeDisposable = CompositeDisposable(),
// private val aapsSchedulers: AapsSchedulers,
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
@ -121,7 +124,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
override fun getPumpStatus(reason: String) {
val throwable = Completable.concat(listOf(
val throwable = Completable.concat(
listOf(
omnipodManager
.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE)
.ignoreElements(),
@ -129,27 +133,50 @@ class OmnipodDashPumpPlugin @Inject constructor(
podStateManager.updateActiveCommand()
.map { handleCommandConfirmation(it) }
.ignoreElement(),
)).blockingGet()
checkPodKaput()
)
).blockingGet()
if (throwable != null) {
aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable)
} else {
aapsLogger.info(LTag.PUMP, "getPumpStatus executed with success")
}
}
private fun checkPodKaput(): Completable = Completable.defer {
val tbr = pumpSync.expectedPumpState().temporaryBasal
if (podStateManager.isPodKaput &&
(tbr == null || tbr.rate != 0.0)
) {
pumpSync.syncTemporaryBasalWithPumpId(
timestamp = System.currentTimeMillis(),
rate = 0.0,
duration = T.mins(PodConstants.MAX_POD_LIFETIME.standardMinutes).msecs(),
isAbsolute = true,
type = PumpSync.TemporaryBasalType.PUMP_SUSPEND,
pumpId = Random.Default.nextLong(), // we don't use this, just make sure it's unique
pumpType = PumpType.OMNIPOD_DASH,
pumpSerial = serialNumber()
)
}
Completable.complete()
}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
val basalProgram = mapProfileToBasalProgram(profile)
return executeSimpleProgrammingCommand(
return executeProgrammingCommand(
pre = suspendDeliveryIfActive(),
historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE),
activeCommandEntry = { historyId ->
podStateManager.createActiveCommand(historyId, basalProgram = basalProgram)
},
command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(),
basalProgram = basalProgram,
post = failWhenUnconfirmed(),
).toPumpEnactResult()
}
private fun failWhenUnconfirmed(): Completable = Completable.defer {
rxBus.send(EventTempBasalChange())
if (podStateManager.activeCommand != null) {
Completable.error(java.lang.IllegalStateException("Command not confirmed"))
} else {
@ -161,9 +188,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED)
Completable.complete()
else
executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
omnipodManager.suspendDelivery()
executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent }
.map {
pumpSyncTempBasal(
@ -172,11 +199,19 @@ class OmnipodDashPumpPlugin @Inject constructor(
PodConstants.MAX_POD_LIFETIME.standardMinutes,
PumpSync.TemporaryBasalType.PUMP_SUSPEND
)
rxBus.send(EventTempBasalChange())
}
.ignoreElements(),
.ignoreElements()
)
}
/* override fun onStop() {
super.onStop()
disposable.clear()
}
*/
private fun observeDeliverySuspended(): Completable = Completable.defer {
if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED)
Completable.complete()
@ -202,7 +237,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
override val baseBasalRate: Double
get() = podStateManager.basalProgram?.rateAt(Date()) ?: 0.0
get() {
val date = Date()
val ret = podStateManager.basalProgram?.rateAt(date) ?: 0.0
aapsLogger.info(LTag.PUMP, "baseBasalRate: %ret at $date}")
return if (podStateManager.alarmType != null) {
0.0
} else
ret
}
override val reservoirLevel: Double
get() {
@ -274,10 +317,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
override fun stopBolusDelivering() {
// TODO update Treatments (?)
executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
omnipodManager.stopBolus().ignoreElements()
aapsLogger.info(LTag.PUMP, "stopBolusDelivering called")
val ret = executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
command = omnipodManager.stopBolus().ignoreElements()
).toPumpEnactResult()
aapsLogger.info(LTag.PUMP, "stopBolusDelivering finished with result: $ret")
}
override fun setTempBasalAbsolute(
@ -288,12 +333,26 @@ class OmnipodDashPumpPlugin @Inject constructor(
tbrType: PumpSync.TemporaryBasalType
): PumpEnactResult {
val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false)
return executeSimpleProgrammingCommand(
aapsLogger.info(
LTag.PUMP,
"setTempBasalAbsolute: $durationInMinutes min :: $absoluteRate U/h :: " +
"enforce: $enforceNew :: tbrType: $tbrType"
)
return executeProgrammingCommand(
historyEntry = history.createRecord(
commandType = OmnipodCommandType.SET_TEMPORARY_BASAL,
tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate)
),
activeCommandEntry = { historyId ->
podStateManager.createActiveCommand(
historyId,
tempBasal = OmnipodDashPodStateManager.TempBasal(
startTime = System.currentTimeMillis(),
rate = absoluteRate,
durationInMinutes = durationInMinutes.toShort(),
)
)
},
command = omnipodManager.setTempBasal(
absoluteRate,
durationInMinutes.toShort(),
@ -302,7 +361,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
.filter { podEvent -> podEvent is PodEvent.CommandSent }
.map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) }
.ignoreElements(),
pre = observeNoActiveTempBasal()
pre = observeNoActiveTempBasal(true),
).toPumpEnactResult()
}
@ -338,20 +397,32 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun observeNoActiveTempBasal(): Completable {
return Completable.defer {
val expectedState = pumpSync.expectedPumpState()
if (expectedState.temporaryBasal == null) {
when {
podStateManager.deliveryStatus !in
arrayOf(DeliveryStatus.TEMP_BASAL_ACTIVE, DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE) -> {
// TODO: what happens if we try to cancel inexistent temp basal?
aapsLogger.info(LTag.PUMP, "No temporary basal to cancel")
Completable.complete()
} else {
}
!enforceNew ->
Completable.error(
IllegalStateException(
"Temporary basal already active and enforeNew is not set."
)
)
else -> {
// enforceNew == true
aapsLogger.info(LTag.PUMP, "Canceling existing temp basal")
executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
omnipodManager.stopTempBasal().ignoreElements()
executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
command = omnipodManager.stopTempBasal().ignoreElements()
)
}
}
}
}
private fun observeActiveTempBasal(): Completable {
@ -386,7 +457,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
return executeSimpleProgrammingCommand(
return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
command = omnipodManager.stopTempBasal().ignoreElements(),
pre = observeActiveTempBasal(),
@ -395,6 +466,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
fun Completable.toPumpEnactResult(): PumpEnactResult {
return this.toSingleDefault(PumpEnactResult(injector).success(true).enacted(true))
.doOnError { throwable ->
aapsLogger.error(LTag.PUMP, "toPumpEnactResult, error executing command: $throwable")
}
.onErrorReturnItem(PumpEnactResult(injector).success(false).enacted(false))
.blockingGet()
}
@ -483,38 +557,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun silenceAlerts(): PumpEnactResult {
// TODO filter alert types
return podStateManager.activeAlerts?.let {
Single.create<PumpEnactResult> { source ->
Observable.concat(
// TODO: is this a programming command? if yes, save to history
omnipodManager.silenceAlerts(it),
history.updateFromState(podStateManager).toObservable(),
podStateManager.updateActiveCommand().toObservable(),
).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.toString()
)
)
},
onComplete = {
aapsLogger.debug("silenceAlerts completed")
source.onSuccess(PumpEnactResult(injector).success(true))
}
)
}.blockingGet()
executeProgrammingCommand(
historyEntry = history.createRecord(commandType = OmnipodCommandType.ACKNOWLEDGE_ALERTS),
command = omnipodManager.silenceAlerts(it).ignoreElements(),
).toPumpEnactResult()
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No active alerts") // TODO i18n
}
private fun suspendDelivery(): PumpEnactResult {
return executeSimpleProgrammingCommand(
return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent }
@ -540,18 +591,18 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun resumeDelivery(): PumpEnactResult {
return profileFunction.getProfile()?.let {
executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements(),
executeProgrammingCommand(
pre = observeDeliverySuspended(),
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements()
).toPumpEnactResult()
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n
}
private fun deactivatePod(): PumpEnactResult {
return executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
omnipodManager.deactivatePod().ignoreElements()
return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
command = omnipodManager.deactivatePod().ignoreElements()
).toPumpEnactResult()
}
@ -566,9 +617,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
private fun playTestBeep(): PumpEnactResult {
return executeSimpleProgrammingCommand(
history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements()
return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
command = omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements()
).toPumpEnactResult()
}
@ -593,11 +644,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
commandQueue.customCommand(CommandHandleTimeChange(false), null)
}
private fun executeSimpleProgrammingCommand(
historyEntry: Single<String>,
command: Completable,
private fun executeProgrammingCommand(
pre: Completable = Completable.complete(),
basalProgram: BasalProgram? = null,
historyEntry: Single<String>,
activeCommandEntry: (historyId: String) -> Single<OmnipodDashPodStateManager.ActiveCommand> =
{ historyId -> podStateManager.createActiveCommand(historyId) },
command: Completable,
post: Completable = Completable.complete(),
): Completable {
return Completable.concat(
@ -605,7 +657,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
pre,
podStateManager.observeNoActiveCommand().ignoreElements(),
historyEntry
.flatMap { podStateManager.createActiveCommand(it, basalProgram) }
.flatMap { activeCommandEntry(it) }
.ignoreElement(),
command.doOnError {
podStateManager.activeCommand?.sendError = it
@ -636,6 +688,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
PumpType.OMNIPOD_DASH,
serialNumber()
)
podStateManager.tempBasal = null
}
OmnipodCommandType.SET_BASAL_PROFILE -> {
@ -662,12 +715,16 @@ class OmnipodDashPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}")
if (!confirmation.success) {
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId())
} else {
podStateManager.tempBasal = command.tempBasal
}
}
OmnipodCommandType.SUSPEND_DELIVERY -> {
if (!confirmation.success) {
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId())
} else {
podStateManager.tempBasal = null
}
}

View file

@ -6,15 +6,10 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.NakResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PodAlarmException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.NakResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
import kotlin.reflect.KClass
@ -88,7 +83,7 @@ class Session(
val response = parseResponse(decrypted)
if (!responseType.isInstance(response)) {
/*if (!responseType.isInstance(response)) {
if (response is AlarmStatusResponse) {
throw PodAlarmException(response)
}
@ -98,6 +93,8 @@ class Session(
throw IllegalResponseException(responseType, response)
}
*/
sessionKeys.msgSequenceNumber++
val ack = getAck(responseMsgPacket)
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack")

View file

@ -28,6 +28,7 @@ interface OmnipodDashPodStateManager {
val isActivationCompleted: Boolean
val isSuspended: Boolean
val isPodRunning: Boolean
val isPodKaput: Boolean
var bluetoothConnectionState: BluetoothConnectionState
val lastUpdatedSystem: Long // System.currentTimeMillis()
@ -57,8 +58,9 @@ interface OmnipodDashPodStateManager {
val deliveryStatus: DeliveryStatus?
val minutesSinceActivation: Short?
val activeAlerts: EnumSet<AlertType>?
val alarmType: AlarmType?
val tempBasal: TempBasal?
var tempBasal: TempBasal?
val tempBasalActive: Boolean
var basalProgram: BasalProgram?
val activeCommand: ActiveCommand?
@ -73,7 +75,8 @@ interface OmnipodDashPodStateManager {
fun updateFromPairing(uniqueId: Id, pairResult: PairResult)
fun reset()
fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null): Single<ActiveCommand>
fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null, tempBasal: TempBasal? = null):
Single<ActiveCommand>
fun updateActiveCommand(): Maybe<CommandConfirmed>
fun observeNoActiveCommand(): Observable<PodEvent>
fun getCommandConfirmationFromState(): CommandConfirmationFromState
@ -84,7 +87,8 @@ interface OmnipodDashPodStateManager {
var sentRealtime: Long = 0,
val historyId: String,
var sendError: Throwable?,
var basalProgram: BasalProgram?
var basalProgram: BasalProgram?,
val tempBasal: TempBasal?
)
// TODO: set created to "now" on boot
data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable

View file

@ -55,6 +55,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
get() = podState.deliveryStatus?.equals(DeliveryStatus.SUSPENDED)
?: false
override val isPodKaput: Boolean
get() = podState.podStatus in arrayOf(PodStatus.ALARM, PodStatus.DEACTIVATED)
override val isPodRunning: Boolean
get() = podState.podStatus?.isRunning() ?: false
@ -137,20 +140,27 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val activeAlerts: EnumSet<AlertType>?
get() = podState.activeAlerts
override val tempBasal: OmnipodDashPodStateManager.TempBasal?
override val alarmType: AlarmType?
get() = podState.alarmType
override var tempBasal: OmnipodDashPodStateManager.TempBasal?
get() = podState.tempBasal
set(tempBasal) {
podState.tempBasal = tempBasal
rxBus.send(EventOmnipodDashPumpValuesChanged())
store()
}
override val tempBasalActive: Boolean
get() = podState.deliveryStatus in
arrayOf(
DeliveryStatus.TEMP_BASAL_ACTIVE,
DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE
)
get() = !isSuspended && tempBasal?.let {
it.startTime + it.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
} ?: false
override var basalProgram: BasalProgram?
get() = podState.basalProgram
set(basalProgram) {
podState.basalProgram = basalProgram
rxBus.send(EventOmnipodDashPumpValuesChanged())
store()
}
@ -188,7 +198,11 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
get() = podState.activeCommand
@Synchronized
override fun createActiveCommand(historyId: String, basalProgram: BasalProgram?):
override fun createActiveCommand(
historyId: String,
basalProgram: BasalProgram?,
tempBasal: OmnipodDashPodStateManager.TempBasal?
):
Single<OmnipodDashPodStateManager.ActiveCommand> {
return Single.create { source ->
if (activeCommand == null) {
@ -198,6 +212,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
historyId = historyId,
sendError = null,
basalProgram = basalProgram,
tempBasal = tempBasal,
)
podState.activeCommand = command
source.onSuccess(command)
@ -308,6 +323,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
}
override fun updateFromDefaultStatusResponse(response: DefaultStatusResponse) {
logger.debug(LTag.PUMPBTCOMM, "Default status reponse :$response")
podState.deliveryStatus = response.deliveryStatus
podState.podStatus = response.podStatus
podState.pulsesDelivered = response.totalPulsesDelivered
@ -374,11 +390,23 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
}
override fun updateFromAlarmStatusResponse(response: AlarmStatusResponse) {
// TODO
logger.error(
logger.info(
LTag.PUMP,
"Not implemented: OmnipodDashPodStateManagerImpl.updateFromAlarmStatusResponse(AlarmStatusResponse)"
"Received AlarmStatusReponse: $response"
)
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
podState.alarmType = response.alarmType
podState.lastUpdatedSystem = System.currentTimeMillis()
podState.lastStatusResponseReceived = SystemClock.elapsedRealtime()
store()
rxBus.send(EventOmnipodDashPumpValuesChanged())
@ -451,6 +479,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
var deliveryStatus: DeliveryStatus? = null
var minutesSinceActivation: Short? = null
var activeAlerts: EnumSet<AlertType>? = null
var alarmType: AlarmType? = null
var basalProgram: BasalProgram? = null
var tempBasal: OmnipodDashPodStateManager.TempBasal? = null

View file

@ -8,9 +8,10 @@ object AlertUtil {
fun decodeAlertSet(encoded: Byte): EnumSet<AlertType> {
val encodedInt = encoded.toInt() and 0xff
val alertList = AlertType.values().filter {
(it.value.toInt() and 0xff) and encodedInt != 0
}.toList()
val alertList = AlertType.values()
.filter { it != AlertType.UNKNOWN } // 0xff && <something> will always be true
.filter { (it.value.toInt() and 0xff) and encodedInt != 0 }
.toList()
return if (alertList.isEmpty()) {
EnumSet.noneOf(AlertType::class.java)

View file

@ -212,7 +212,6 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
}
private fun updateUi() {
// TODO update bluetooth status
updateBluetoothStatus()
updateOmnipodStatus()
updatePodActionButtons()
@ -296,6 +295,15 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
errors.add(resourceHelper.gs(R.string.omnipod_common_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name))
}
*/
podStateManager.alarmType?.let {
errors.add(
resourceHelper.gs(
R.string.omnipod_common_pod_status_pod_fault_description,
it.value,
it.toString()
)
)
}
// base basal rate
podInfoBinding.baseBasalRate.text = if (podStateManager.basalProgram != null && !podStateManager.isSuspended) {
@ -343,7 +351,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
)
}
podInfoBinding.podActiveAlerts.text = PLACEHOLDER
podInfoBinding.podActiveAlerts.text = podStateManager.activeAlerts?.let {
it.map { it.toString() }.joinToString(",")
} ?: PLACEHOLDER
}
if (errors.size == 0) {
@ -503,7 +513,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
}
private fun updateSilenceAlertsButton() {
if (isAutomaticallySilenceAlertsEnabled() && podStateManager.isPodRunning &&
if (!isAutomaticallySilenceAlertsEnabled() &&
podStateManager.isPodRunning &&
(
podStateManager.activeAlerts!!.size > 0 ||
commandQueue.isCustomCommandInQueue(CommandSilenceAlerts::class.java)