Merge pull request #15 from 0pen-dash/bart/improvements

Some improvements
This commit is contained in:
Andrei Vereha 2021-03-01 11:06:31 +01:00 committed by GitHub
commit 07c6a95145
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 146 additions and 213 deletions

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertSlot import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import io.reactivex.Observable import io.reactivex.Observable
import java.util.* import java.util.*
@ -33,7 +33,7 @@ interface OmnipodDashManager {
fun programAlerts(alertConfigurations: List<AlertConfiguration>): Observable<PodEvent> fun programAlerts(alertConfigurations: List<AlertConfiguration>): Observable<PodEvent>
fun silenceAlerts(alerts: EnumSet<AlertSlot>): Observable<PodEvent> fun silenceAlerts(alerts: EnumSet<AlertType>): Observable<PodEvent>
fun deactivatePod(): Observable<PodEvent> fun deactivatePod(): Observable<PodEvent>
} }

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.G
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.GetVersionCommand.Companion.DEFAULT_UNIQUE_ID import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.GetVersionCommand.Companion.DEFAULT_UNIQUE_ID
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertSlot import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse
@ -17,9 +17,11 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
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.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.rx.retryWithBackoff
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.functions.Consumer import io.reactivex.functions.Consumer
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -41,7 +43,7 @@ class OmnipodDashManagerImpl @Inject constructor(
} }
private val observeConnectToPod: Observable<PodEvent> private val observeConnectToPod: Observable<PodEvent>
get() = Observable.defer { bleManager.connect() } get() = Observable.defer { bleManager.connect().retryWithBackoff(retries = 2, delay = 3, timeUnit = TimeUnit.SECONDS) } // TODO are these reasonable values?
private val observeSendGetVersionCommand: Observable<PodEvent> private val observeSendGetVersionCommand: Observable<PodEvent>
get() = Observable.defer { get() = Observable.defer {
@ -119,7 +121,7 @@ class OmnipodDashManagerImpl @Inject constructor(
return Observable.empty() return Observable.empty()
} }
override fun silenceAlerts(alerts: EnumSet<AlertSlot>): Observable<PodEvent> { override fun silenceAlerts(alerts: EnumSet<AlertType>): Observable<PodEvent> {
// TODO // TODO
return Observable.empty() return Observable.empty()
} }

View file

@ -53,14 +53,14 @@ class ProgramAlertsCommand private constructor(
private var alertConfigurations: List<AlertConfiguration>? = null private var alertConfigurations: List<AlertConfiguration>? = null
fun setAlertConfigurations(alertConfigurations: List<AlertConfiguration>?): Builder { fun setAlertConfigurations(alertConfigurations: List<AlertConfiguration>): Builder {
this.alertConfigurations = alertConfigurations this.alertConfigurations = alertConfigurations
return this return this
} }
override fun buildCommand(): ProgramAlertsCommand { override fun buildCommand(): ProgramAlertsCommand {
requireNotNull(alertConfigurations) { "alertConfigurations can not be null" } // !!? requireNotNull(alertConfigurations) { "alertConfigurations can not be null" }
return ProgramAlertsCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, alertConfigurations!!, nonce!!) // TODO this might crash if not all are set return ProgramAlertsCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, alertConfigurations!!, nonce!!)
} }
} }

View file

@ -77,17 +77,17 @@ class ProgramBasalCommand private constructor(
private var programReminder: ProgramReminder? = null private var programReminder: ProgramReminder? = null
private var currentTime: Date? = null private var currentTime: Date? = null
fun setBasalProgram(basalProgram: BasalProgram?): Builder { fun setBasalProgram(basalProgram: BasalProgram): Builder {
this.basalProgram = basalProgram this.basalProgram = basalProgram
return this return this
} }
fun setProgramReminder(programReminder: ProgramReminder?): Builder { fun setProgramReminder(programReminder: ProgramReminder): Builder {
this.programReminder = programReminder this.programReminder = programReminder
return this return this
} }
fun setCurrentTime(currentTime: Date?): Builder { fun setCurrentTime(currentTime: Date): Builder {
this.currentTime = currentTime this.currentTime = currentTime
return this return this
} }

View file

@ -70,7 +70,7 @@ class ProgramBolusCommand private constructor(
return this return this
} }
fun setProgramReminder(programReminder: ProgramReminder?): Builder { fun setProgramReminder(programReminder: ProgramReminder): Builder {
this.programReminder = programReminder this.programReminder = programReminder
return this return this
} }

View file

@ -32,7 +32,7 @@ class ProgramTempBasalCommand private constructor(
private var rateInUnitsPerHour: Double? = null private var rateInUnitsPerHour: Double? = null
private var durationInMinutes: Short? = null private var durationInMinutes: Short? = null
fun setProgramReminder(programReminder: ProgramReminder?): Builder { fun setProgramReminder(programReminder: ProgramReminder): Builder {
this.programReminder = programReminder this.programReminder = programReminder
return this return this
} }

View file

@ -56,7 +56,7 @@ class SetUniqueIdCommand private constructor(
return this return this
} }
fun setInitializationTime(initializationTime: Date?): Builder { fun setInitializationTime(initializationTime: Date): Builder {
this.initializationTime = initializationTime this.initializationTime = initializationTime
return this return this
} }

View file

@ -3,7 +3,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.NonceEnabledCommand
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.builder.NonceEnabledCommandBuilder
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.Encodable import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.AlertUtil
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.* import java.util.*
@ -11,7 +12,7 @@ class SilenceAlertsCommand private constructor(
uniqueId: Int, uniqueId: Int,
sequenceNumber: Short, sequenceNumber: Short,
multiCommandFlag: Boolean, multiCommandFlag: Boolean,
private val parameters: SilenceAlertCommandParameters, private val alertTypes: EnumSet<AlertType>,
nonce: Int nonce: Int
) : NonceEnabledCommand(CommandType.SILENCE_ALERTS, uniqueId, sequenceNumber, multiCommandFlag, nonce) { ) : NonceEnabledCommand(CommandType.SILENCE_ALERTS, uniqueId, sequenceNumber, multiCommandFlag, nonce) {
@ -22,12 +23,12 @@ class SilenceAlertsCommand private constructor(
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.putInt(nonce) // .putInt(nonce) //
.put(parameters.encoded) // .put(AlertUtil.encodeAlertSet(alertTypes)) //
.array()) .array())
override fun toString(): String { override fun toString(): String {
return "SilenceAlertsCommand{" + return "SilenceAlertsCommand{" +
"parameters=" + parameters + "alertTypes=" + alertTypes +
", nonce=" + nonce + ", nonce=" + nonce +
", commandType=" + commandType + ", commandType=" + commandType +
", uniqueId=" + uniqueId + ", uniqueId=" + uniqueId +
@ -36,76 +37,18 @@ class SilenceAlertsCommand private constructor(
'}' '}'
} }
class SilenceAlertCommandParameters(private val silenceAutoOffAlert: Boolean, private val silenceMultiCommandAlert: Boolean, private val silenceExpirationImminentAlert: Boolean, private val silenceUserSetExpirationAlert: Boolean, private val silenceLowReservoirAlert: Boolean, private val silenceSuspendInProgressAlert: Boolean, private val silenceSuspendEndedAlert: Boolean, private val silencePodExpirationAlert: Boolean) : Encodable {
override val encoded: ByteArray
get() {
val bitSet = BitSet(8)
bitSet[0] = silenceAutoOffAlert
bitSet[1] = silenceMultiCommandAlert
bitSet[2] = silenceExpirationImminentAlert
bitSet[3] = silenceUserSetExpirationAlert
bitSet[4] = silenceLowReservoirAlert
bitSet[5] = silenceSuspendInProgressAlert
bitSet[6] = silenceSuspendEndedAlert
bitSet[7] = silencePodExpirationAlert
return bitSet.toByteArray()
}
}
class Builder : NonceEnabledCommandBuilder<Builder, SilenceAlertsCommand>() { class Builder : NonceEnabledCommandBuilder<Builder, SilenceAlertsCommand>() {
private var silenceAutoOffAlert = false private var alertTypes: EnumSet<AlertType>? = null
private var silenceMultiCommandAlert = false
private var silenceExpirationImminentAlert = false
private var silenceUserSetExpirationAlert = false
private var silenceLowReservoirAlert = false
private var silenceSuspendInProgressAlert = false
private var silenceSuspendEndedAlert = false
private var silencePodExpirationAlert = false
fun setSilenceAutoOffAlert(silenceAutoOffAlert: Boolean): Builder { fun setAlertTypes(alertTypes: EnumSet<AlertType>): Builder {
this.silenceAutoOffAlert = silenceAutoOffAlert this.alertTypes = alertTypes
return this
}
fun setSilenceMultiCommandAlert(silenceMultiCommandAlert: Boolean): Builder {
this.silenceMultiCommandAlert = silenceMultiCommandAlert
return this
}
fun setSilenceExpirationImminentAlert(silenceExpirationImminentAlert: Boolean): Builder {
this.silenceExpirationImminentAlert = silenceExpirationImminentAlert
return this
}
fun setSilenceUserSetExpirationAlert(silenceUserSetExpirationAlert: Boolean): Builder {
this.silenceUserSetExpirationAlert = silenceUserSetExpirationAlert
return this
}
fun setSilenceLowReservoirAlert(silenceLowReservoirAlert: Boolean): Builder {
this.silenceLowReservoirAlert = silenceLowReservoirAlert
return this
}
fun setSilenceSuspendInProgressAlert(silenceSuspendInProgressAlert: Boolean): Builder {
this.silenceSuspendInProgressAlert = silenceSuspendInProgressAlert
return this
}
fun setSilenceSuspendEndedAlert(silenceSuspendEndedAlert: Boolean): Builder {
this.silenceSuspendEndedAlert = silenceSuspendEndedAlert
return this
}
fun setSilencePodExpirationAlert(silencePodExpirationAlert: Boolean): Builder {
this.silencePodExpirationAlert = silencePodExpirationAlert
return this return this
} }
override fun buildCommand(): SilenceAlertsCommand { override fun buildCommand(): SilenceAlertsCommand {
return SilenceAlertsCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, SilenceAlertCommandParameters(silenceAutoOffAlert, silenceMultiCommandAlert, silenceExpirationImminentAlert, silenceUserSetExpirationAlert, silenceLowReservoirAlert, silenceSuspendInProgressAlert, silenceSuspendEndedAlert, silencePodExpirationAlert), nonce!!) requireNotNull(alertTypes) { "alertTypes can not be null" }
return SilenceAlertsCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, alertTypes!!, nonce!!)
} }
} }

View file

@ -58,12 +58,12 @@ class StopDeliveryCommand private constructor(
private var deliveryType: DeliveryType? = null private var deliveryType: DeliveryType? = null
private var beepType: BeepType? = BeepType.LONG_SINGLE_BEEP private var beepType: BeepType? = BeepType.LONG_SINGLE_BEEP
fun setDeliveryType(deliveryType: DeliveryType?): Builder { fun setDeliveryType(deliveryType: DeliveryType): Builder {
this.deliveryType = deliveryType this.deliveryType = deliveryType
return this return this
} }
fun setBeepType(beepType: BeepType?): Builder { fun setBeepType(beepType: BeepType): Builder {
this.beepType = beepType this.beepType = beepType
return this return this
} }

View file

@ -4,23 +4,22 @@ import java.nio.ByteBuffer
import kotlin.experimental.or import kotlin.experimental.or
class AlertConfiguration( class AlertConfiguration(
private val slot: AlertSlot, private val type: AlertType,
private val enabled: Boolean, private val enabled: Boolean,
private val durationInMinutes: Short, private val durationInMinutes: Short,
private val autoOff: Boolean, private val autoOff: Boolean,
private val triggerType: AlertTriggerType, private val trigger: AlertTrigger,
private val offsetInMinutesOrThresholdInMicroLiters: Short,
private val beepType: BeepType, private val beepType: BeepType,
private val beepRepetition: BeepRepetitionType private val beepRepetition: BeepRepetitionType
) : Encodable { ) : Encodable {
override val encoded: ByteArray override val encoded: ByteArray
get() { get() {
var firstByte = (slot.value.toInt() shl 4).toByte() var firstByte = (type.index.toInt() shl 4).toByte()
if (enabled) { if (enabled) {
firstByte = firstByte or (1 shl 3) firstByte = firstByte or (1 shl 3)
} }
if (triggerType == AlertTriggerType.RESERVOIR_VOLUME_TRIGGER) { if (trigger is AlertTrigger.ReservoirVolumeTrigger) {
firstByte = firstByte or (1 shl 2) firstByte = firstByte or (1 shl 2)
} }
if (autoOff) { if (autoOff) {
@ -30,7 +29,15 @@ class AlertConfiguration(
return ByteBuffer.allocate(6) // return ByteBuffer.allocate(6) //
.put(firstByte) .put(firstByte)
.put(durationInMinutes.toByte()) // .put(durationInMinutes.toByte()) //
.putShort(offsetInMinutesOrThresholdInMicroLiters) // .putShort(when (trigger) {
is AlertTrigger.ReservoirVolumeTrigger -> {
trigger.thresholdInMicroLiters
}
is AlertTrigger.TimerTrigger -> {
trigger.offsetInMinutes
}
}) //
.put(beepRepetition.value) // .put(beepRepetition.value) //
.put(beepType.value) // .put(beepType.value) //
.array() .array()
@ -38,12 +45,11 @@ class AlertConfiguration(
override fun toString(): String { override fun toString(): String {
return "AlertConfiguration{" + return "AlertConfiguration{" +
"slot=" + slot + "type=" + type +
", enabled=" + enabled + ", enabled=" + enabled +
", durationInMinutes=" + durationInMinutes + ", durationInMinutes=" + durationInMinutes +
", autoOff=" + autoOff + ", autoOff=" + autoOff +
", triggerType=" + triggerType + ", trigger=" + trigger +
", offsetInMinutesOrThresholdInMicroLiters=" + offsetInMinutesOrThresholdInMicroLiters +
", beepType=" + beepType + ", beepType=" + beepType +
", beepRepetition=" + beepRepetition + ", beepRepetition=" + beepRepetition +
'}' '}'

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition
sealed class AlertTrigger {
class TimerTrigger(val offsetInMinutes: Short) : AlertTrigger()
class ReservoirVolumeTrigger(val thresholdInMicroLiters: Short) : AlertTrigger()
}

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition
enum class AlertTriggerType {
TIME_TRIGGER,
RESERVOIR_VOLUME_TRIGGER
}

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definiti
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.HasValue import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.HasValue
enum class AlertSlot(override val value: Byte) : HasValue { enum class AlertType(val index: Byte) : HasValue {
AUTO_OFF(0x00.toByte()), AUTO_OFF(0x00.toByte()),
MULTI_COMMAND(0x01.toByte()), MULTI_COMMAND(0x01.toByte()),
@ -13,4 +13,11 @@ enum class AlertSlot(override val value: Byte) : HasValue {
SUSPEND_ENDED(0x06.toByte()), SUSPEND_ENDED(0x06.toByte()),
EXPIRATION(0x07.toByte()), EXPIRATION(0x07.toByte()),
UNKNOWN(0xff.toByte()); UNKNOWN(0xff.toByte());
override val value: Byte
get() = if (this == UNKNOWN) {
0xff.toByte()
} else {
(1 shl index.toInt()).toByte()
}
} }

View file

@ -1,11 +1,14 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlarmType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlarmType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType.StatusResponseType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType.StatusResponseType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.AlertUtil
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.*
import kotlin.experimental.and import kotlin.experimental.and
class AlarmStatusResponse( class AlarmStatusResponse(
@ -24,14 +27,7 @@ class AlarmStatusResponse(
val alarmTime: Short = ByteBuffer.wrap(byteArrayOf(encoded[11], encoded[12])).short val alarmTime: Short = ByteBuffer.wrap(byteArrayOf(encoded[11], encoded[12])).short
val reservoirPulsesRemaining: Short = ByteBuffer.wrap(byteArrayOf(encoded[13], encoded[14])).short val reservoirPulsesRemaining: Short = ByteBuffer.wrap(byteArrayOf(encoded[13], encoded[14])).short
val minutesSinceActivation: Short = ByteBuffer.wrap(byteArrayOf(encoded[15], encoded[16])).short val minutesSinceActivation: Short = ByteBuffer.wrap(byteArrayOf(encoded[15], encoded[16])).short
val alert0Active: Boolean val activeAlerts: EnumSet<AlertType> = AlertUtil.decodeAlertSet(encoded[17])
val alert1Active: Boolean
val alert2Active: Boolean
val alert3Active: Boolean
val alert4Active: Boolean
val alert5Active: Boolean
val alert6Active: Boolean
val alert7Active: Boolean
val occlusionAlarm: Boolean val occlusionAlarm: Boolean
val pulseInfoInvalid: Boolean val pulseInfoInvalid: Boolean
val podStatusWhenAlarmOccurred: PodStatus val podStatusWhenAlarmOccurred: PodStatus
@ -44,15 +40,6 @@ class AlarmStatusResponse(
val returnAddressOfPodAlarmHandlerCaller: Short val returnAddressOfPodAlarmHandlerCaller: Short
init { init {
val activeAlerts = encoded[17].toInt()
alert0Active = activeAlerts and 1 == 1
alert1Active = activeAlerts ushr 1 and 1 == 1
alert2Active = activeAlerts ushr 2 and 1 == 1
alert3Active = activeAlerts ushr 3 and 1 == 1
alert4Active = activeAlerts ushr 4 and 1 == 1
alert5Active = activeAlerts ushr 5 and 1 == 1
alert6Active = activeAlerts ushr 6 and 1 == 1
alert7Active = activeAlerts ushr 7 and 1 == 1
val alarmFlags = encoded[18] val alarmFlags = encoded[18]
occlusionAlarm = (alarmFlags.toInt() and 1) == 1 occlusionAlarm = (alarmFlags.toInt() and 1) == 1
pulseInfoInvalid = alarmFlags shr 1 and 1 == 1 pulseInfoInvalid = alarmFlags shr 1 and 1 == 1
@ -69,44 +56,33 @@ class AlarmStatusResponse(
} }
override fun toString(): String { override fun toString(): String {
return "AlarmStatusResponse{" + return "AlarmStatusResponse(" +
"messageType=" + messageType + "messageType=$messageType, " +
", messageLength=" + messageLength + "messageLength=$messageLength, " +
", additionalStatusResponseType=" + additionalStatusResponseType + "additionalStatusResponseType=$additionalStatusResponseType, " +
", podStatus=" + podStatus + "podStatus=$podStatus, " +
", deliveryStatus=" + deliveryStatus + "deliveryStatus=$deliveryStatus, " +
", bolusPulsesRemaining=" + bolusPulsesRemaining + "bolusPulsesRemaining=$bolusPulsesRemaining, " +
", sequenceNumberOfLastProgrammingCommand=" + sequenceNumberOfLastProgrammingCommand + "sequenceNumberOfLastProgrammingCommand=$sequenceNumberOfLastProgrammingCommand, " +
", totalPulsesDelivered=" + totalPulsesDelivered + "totalPulsesDelivered=$totalPulsesDelivered, " +
", alarmType=" + alarmType + "alarmType=$alarmType, " +
", alarmTime=" + alarmTime + "alarmTime=$alarmTime, " +
", reservoirPulsesRemaining=" + reservoirPulsesRemaining + "reservoirPulsesRemaining=$reservoirPulsesRemaining, " +
", minutesSinceActivation=" + minutesSinceActivation + "minutesSinceActivation=$minutesSinceActivation, " +
", alert0Active=" + alert0Active + "activeAlerts=$activeAlerts, " +
", alert1Active=" + alert1Active + "occlusionAlarm=$occlusionAlarm, " +
", alert2Active=" + alert2Active + "pulseInfoInvalid=$pulseInfoInvalid, " +
", alert3Active=" + alert3Active + "podStatusWhenAlarmOccurred=$podStatusWhenAlarmOccurred, " +
", alert4Active=" + alert4Active + "immediateBolusWhenAlarmOccurred=$immediateBolusWhenAlarmOccurred, " +
", alert5Active=" + alert5Active + "occlusionType=$occlusionType, " +
", alert6Active=" + alert6Active + "occurredWhenFetchingImmediateBolusActiveInformation=$occurredWhenFetchingImmediateBolusActiveInformation, " +
", alert7Active=" + alert7Active + "rssi=$rssi, " +
", occlusionAlarm=" + occlusionAlarm + "receiverLowerGain=$receiverLowerGain, " +
", pulseInfoInvalid=" + pulseInfoInvalid + "podStatusWhenAlarmOccurred2=$podStatusWhenAlarmOccurred2, " +
", podStatusWhenAlarmOccurred=" + podStatusWhenAlarmOccurred + "returnAddressOfPodAlarmHandlerCaller=$returnAddressOfPodAlarmHandlerCaller" +
", immediateBolusWhenAlarmOccurred=" + immediateBolusWhenAlarmOccurred + ")"
", occlusionType=" + occlusionType +
", occurredWhenFetchingImmediateBolusActiveInformation=" + occurredWhenFetchingImmediateBolusActiveInformation +
", rssi=" + rssi +
", receiverLowerGain=" + receiverLowerGain +
", podStatusWhenAlarmOccurred2=" + podStatusWhenAlarmOccurred2 +
", returnAddressOfPodAlarmHandlerCaller=" + returnAddressOfPodAlarmHandlerCaller +
", statusResponseType=" + statusResponseType +
", responseType=" + responseType +
", encoded=" + encoded.contentToString() +
'}'
} }
infix fun Byte.shr(i: Int): Int = toInt() shr i infix fun Byte.shr(i: Int): Int = toInt() shr i
} }

View file

@ -1,8 +1,11 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.AlertUtil
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue
import java.util.*
import kotlin.experimental.and import kotlin.experimental.and
class DefaultStatusResponse( class DefaultStatusResponse(
@ -15,42 +18,24 @@ class DefaultStatusResponse(
val totalPulsesDelivered: Short = ((encoded[2] and 0x0f shl 12 or (encoded[3].toInt() and 0xff shl 1) or (encoded[4].toInt() and 0xff ushr 7)).toShort()) val totalPulsesDelivered: Short = ((encoded[2] and 0x0f shl 12 or (encoded[3].toInt() and 0xff shl 1) or (encoded[4].toInt() and 0xff ushr 7)).toShort())
val sequenceNumberOfLastProgrammingCommand: Short = (encoded[4] ushr 3 and 0x0f).toShort() val sequenceNumberOfLastProgrammingCommand: Short = (encoded[4] ushr 3 and 0x0f).toShort()
val bolusPulsesRemaining: Short = ((encoded[4] and 0x07 shl 10 or (encoded[5].toInt() and 0xff) and 2047).toShort()) val bolusPulsesRemaining: Short = ((encoded[4] and 0x07 shl 10 or (encoded[5].toInt() and 0xff) and 2047).toShort())
val activeAlerts = (encoded[6].toInt() and 0xff shl 1 or (encoded[7] ushr 7)).toShort() val activeAlerts: EnumSet<AlertType> = AlertUtil.decodeAlertSet((encoded[6].toInt() and 0xff shl 1 or (encoded[7] ushr 7)).toByte())
val occlusionAlertActive: Boolean = (activeAlerts and 1).toInt() == 1
val alert1Active: Boolean = activeAlerts shr 1 and 1 == 1
val alert2Active: Boolean = activeAlerts shr 2 and 1 == 1
val alert3Active: Boolean = activeAlerts shr 3 and 1 == 1
val alert4Active: Boolean = activeAlerts shr 4 and 1 == 1
val alert5Active: Boolean = activeAlerts shr 5 and 1 == 1
val alert6Active: Boolean = activeAlerts shr 6 and 1 == 1
val alert7Active: Boolean = activeAlerts shr 7 and 1 == 1
val minutesSinceActivation: Short = (encoded[7] and 0x7f shl 6 or (encoded[8].toInt() and 0xff ushr 2 and 0x3f)).toShort() val minutesSinceActivation: Short = (encoded[7] and 0x7f shl 6 or (encoded[8].toInt() and 0xff ushr 2 and 0x3f)).toShort()
val reservoirPulsesRemaining: Short = (encoded[8] shl 8 or encoded[9].toInt() and 0x3ff).toShort() val reservoirPulsesRemaining: Short = (encoded[8] shl 8 or encoded[9].toInt() and 0x3ff).toShort()
override fun toString(): String { override fun toString(): String {
return "DefaultStatusResponse{" + return "DefaultStatusResponse(" +
"messageType=" + messageType + "messageType=$messageType" +
", deliveryStatus=" + deliveryStatus + ", deliveryStatus=$deliveryStatus" +
", podStatus=" + podStatus + ", podStatus=$podStatus" +
", totalPulsesDelivered=" + totalPulsesDelivered + ", totalPulsesDelivered=$totalPulsesDelivered" +
", sequenceNumberOfLastProgrammingCommand=" + sequenceNumberOfLastProgrammingCommand + ", sequenceNumberOfLastProgrammingCommand=$sequenceNumberOfLastProgrammingCommand" +
", bolusPulsesRemaining=" + bolusPulsesRemaining + ", bolusPulsesRemaining=$bolusPulsesRemaining" +
", occlusionAlertActive=" + occlusionAlertActive + ", activeAlerts=$activeAlerts" +
", alert1Active=" + alert1Active + ", minutesSinceActivation=$minutesSinceActivation" +
", alert2Active=" + alert2Active + ", reservoirPulsesRemaining=$reservoirPulsesRemaining)"
", alert3Active=" + alert3Active +
", alert4Active=" + alert4Active +
", alert5Active=" + alert5Active +
", alert6Active=" + alert6Active +
", alert7Active=" + alert7Active +
", minutesSinceActivation=" + minutesSinceActivation +
", reservoirPulsesRemaining=" + reservoirPulsesRemaining +
", responseType=" + responseType +
", encoded=" + encoded.contentToString() +
'}'
} }
} }
infix fun Byte.ushr(i: Int) = toInt() ushr i infix fun Byte.ushr(i: Int) = toInt() ushr i
infix fun Short.shr(i: Int): Int = toInt() shr i
infix fun Byte.shl(i: Int): Int = toInt() shl i infix fun Byte.shl(i: Int): Int = toInt() shl i

View file

@ -39,7 +39,7 @@ interface OmnipodDashPodStateManager {
val podStatus: PodStatus? val podStatus: PodStatus?
val deliveryStatus: DeliveryStatus? val deliveryStatus: DeliveryStatus?
val minutesSinceActivation: Short? val minutesSinceActivation: Short?
val activeAlerts: EnumSet<AlertSlot>? val activeAlerts: EnumSet<AlertType>?
val tempBasal: TempBasal? val tempBasal: TempBasal?
val tempBasalActive: Boolean val tempBasalActive: Boolean

View file

@ -130,7 +130,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val minutesSinceActivation: Short? override val minutesSinceActivation: Short?
get() = podState.minutesSinceActivation get() = podState.minutesSinceActivation
override val activeAlerts: EnumSet<AlertSlot>? override val activeAlerts: EnumSet<AlertType>?
get() = podState.activeAlerts get() = podState.activeAlerts
override val tempBasal: OmnipodDashPodStateManager.TempBasal? override val tempBasal: OmnipodDashPodStateManager.TempBasal?
@ -154,8 +154,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
podState.pulsesRemaining = response.reservoirPulsesRemaining podState.pulsesRemaining = response.reservoirPulsesRemaining
podState.sequenceNumberOfLastProgrammingCommand = response.sequenceNumberOfLastProgrammingCommand podState.sequenceNumberOfLastProgrammingCommand = response.sequenceNumberOfLastProgrammingCommand
podState.minutesSinceActivation = response.minutesSinceActivation podState.minutesSinceActivation = response.minutesSinceActivation
podState.activeAlerts = response.activeAlerts
// TODO active alerts
podState.lastUpdated = System.currentTimeMillis() podState.lastUpdated = System.currentTimeMillis()
store() store()
@ -247,7 +246,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
var podStatus: PodStatus? = null var podStatus: PodStatus? = null
var deliveryStatus: DeliveryStatus? = null var deliveryStatus: DeliveryStatus? = null
var minutesSinceActivation: Short? = null var minutesSinceActivation: Short? = null
var activeAlerts: EnumSet<AlertSlot>? = null var activeAlerts: EnumSet<AlertType>? = null
var basalProgram: BasalProgram? = null var basalProgram: BasalProgram? = null
var tempBasal: OmnipodDashPodStateManager.TempBasal? = null var tempBasal: OmnipodDashPodStateManager.TempBasal? = null

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import java.util.*
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()
return if (alertList.isEmpty()) {
EnumSet.noneOf(AlertType::class.java)
} else {
EnumSet.copyOf(alertList)
}
}
fun encodeAlertSet(alertSet: EnumSet<AlertType>): Byte =
alertSet.fold(0,
{ out, slot ->
out or (slot.value.toInt() and 0xff)
}
).toByte()
}

View file

@ -1,8 +1,8 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertSlot import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTriggerType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTrigger
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepRepetitionType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepRepetitionType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import org.apache.commons.codec.DecoderException import org.apache.commons.codec.DecoderException
@ -15,8 +15,8 @@ class ProgramAlertsCommandTest {
@Test @Throws(DecoderException::class) fun testExpirationAlerts() { @Test @Throws(DecoderException::class) fun testExpirationAlerts() {
val configurations: MutableList<AlertConfiguration> = ArrayList() val configurations: MutableList<AlertConfiguration> = ArrayList()
configurations.add(AlertConfiguration(AlertSlot.EXPIRATION, true, 420.toShort(), false, AlertTriggerType.TIME_TRIGGER, 4305.toShort(), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX3)) configurations.add(AlertConfiguration(AlertType.EXPIRATION, true, 420.toShort(), false, AlertTrigger.TimerTrigger(4305.toShort()), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX3))
configurations.add(AlertConfiguration(AlertSlot.EXPIRATION_IMMINENT, true, 0.toShort(), false, AlertTriggerType.TIME_TRIGGER, 4725.toShort(), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX4)) configurations.add(AlertConfiguration(AlertType.EXPIRATION_IMMINENT, true, 0.toShort(), false, AlertTrigger.TimerTrigger(4725.toShort()), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX4))
val encoded = ProgramAlertsCommand.Builder() // val encoded = ProgramAlertsCommand.Builder() //
.setUniqueId(37879811) // .setUniqueId(37879811) //
@ -32,7 +32,7 @@ class ProgramAlertsCommandTest {
@Test @Throws(DecoderException::class) fun testLowReservoirAlert() { @Test @Throws(DecoderException::class) fun testLowReservoirAlert() {
val configurations: MutableList<AlertConfiguration> = ArrayList() val configurations: MutableList<AlertConfiguration> = ArrayList()
configurations.add(AlertConfiguration(AlertSlot.LOW_RESERVOIR, true, 0.toShort(), false, AlertTriggerType.RESERVOIR_VOLUME_TRIGGER, 200.toShort(), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX)) configurations.add(AlertConfiguration(AlertType.LOW_RESERVOIR, true, 0.toShort(), false, AlertTrigger.ReservoirVolumeTrigger(200.toShort()), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX))
val encoded = ProgramAlertsCommand.Builder() // val encoded = ProgramAlertsCommand.Builder() //
.setUniqueId(37879811) // .setUniqueId(37879811) //
@ -47,7 +47,7 @@ class ProgramAlertsCommandTest {
@Test @Throws(DecoderException::class) fun testUserExpirationAlert() { @Test @Throws(DecoderException::class) fun testUserExpirationAlert() {
val configurations: MutableList<AlertConfiguration> = ArrayList() val configurations: MutableList<AlertConfiguration> = ArrayList()
configurations.add(AlertConfiguration(AlertSlot.USER_SET_EXPIRATION, true, 0.toShort(), false, AlertTriggerType.TIME_TRIGGER, 4079.toShort(), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX2)) configurations.add(AlertConfiguration(AlertType.USER_SET_EXPIRATION, true, 0.toShort(), false, AlertTrigger.TimerTrigger(4079.toShort()), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX2))
val encoded = ProgramAlertsCommand.Builder() // val encoded = ProgramAlertsCommand.Builder() //
.setUniqueId(37879811) // .setUniqueId(37879811) //
@ -62,7 +62,7 @@ class ProgramAlertsCommandTest {
@Test @Throws(DecoderException::class) fun testLumpOfCoalAlert() { @Test @Throws(DecoderException::class) fun testLumpOfCoalAlert() {
val configurations: MutableList<AlertConfiguration> = ArrayList() val configurations: MutableList<AlertConfiguration> = ArrayList()
configurations.add(AlertConfiguration(AlertSlot.EXPIRATION, true, 55.toShort(), false, AlertTriggerType.TIME_TRIGGER, 5.toShort(), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX5)) configurations.add(AlertConfiguration(AlertType.EXPIRATION, true, 55.toShort(), false, AlertTrigger.TimerTrigger(5.toShort()), BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX5))
val encoded = ProgramAlertsCommand.Builder() // val encoded = ProgramAlertsCommand.Builder() //
.setUniqueId(37879811) // .setUniqueId(37879811) //

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import org.apache.commons.codec.DecoderException import org.apache.commons.codec.DecoderException
import org.apache.commons.codec.binary.Hex import org.apache.commons.codec.binary.Hex
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import java.util.*
class SilenceAlertsCommandTest { class SilenceAlertsCommandTest {
@ -12,7 +14,7 @@ class SilenceAlertsCommandTest {
.setUniqueId(37879811) // .setUniqueId(37879811) //
.setSequenceNumber(1.toShort()) // .setSequenceNumber(1.toShort()) //
.setNonce(1229869870) // .setNonce(1229869870) //
.setSilenceLowReservoirAlert(true) // .setAlertTypes(EnumSet.of(AlertType.LOW_RESERVOIR)) //
.build() // .build() //
.encoded .encoded

View file

@ -29,14 +29,7 @@ class AlarmStatusResponseTest {
Assert.assertEquals(0.toShort(), response.alarmTime) Assert.assertEquals(0.toShort(), response.alarmTime)
Assert.assertEquals(1023.toShort(), response.reservoirPulsesRemaining) Assert.assertEquals(1023.toShort(), response.reservoirPulsesRemaining)
Assert.assertEquals(405.toShort(), response.minutesSinceActivation) Assert.assertEquals(405.toShort(), response.minutesSinceActivation)
Assert.assertFalse(response.alert0Active) Assert.assertEquals(0, response.activeAlerts.size)
Assert.assertFalse(response.alert1Active)
Assert.assertFalse(response.alert2Active)
Assert.assertFalse(response.alert3Active)
Assert.assertFalse(response.alert4Active)
Assert.assertFalse(response.alert5Active)
Assert.assertFalse(response.alert6Active)
Assert.assertFalse(response.alert7Active)
Assert.assertFalse(response.occlusionAlarm) Assert.assertFalse(response.occlusionAlarm)
Assert.assertFalse(response.pulseInfoInvalid) Assert.assertFalse(response.pulseInfoInvalid)
Assert.assertEquals(PodStatus.UNINITIALIZED, response.podStatusWhenAlarmOccurred) Assert.assertEquals(PodStatus.UNINITIALIZED, response.podStatusWhenAlarmOccurred)

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType
import org.apache.commons.codec.DecoderException import org.apache.commons.codec.DecoderException
import org.apache.commons.codec.binary.Hex import org.apache.commons.codec.binary.Hex
import org.junit.Assert import org.junit.Assert
@ -22,14 +21,7 @@ class DefaultStatusResponseTest {
Assert.assertEquals(320.toShort(), response.totalPulsesDelivered) Assert.assertEquals(320.toShort(), response.totalPulsesDelivered)
Assert.assertEquals(5.toShort(), response.sequenceNumberOfLastProgrammingCommand) Assert.assertEquals(5.toShort(), response.sequenceNumberOfLastProgrammingCommand)
Assert.assertEquals(0.toShort(), response.bolusPulsesRemaining) Assert.assertEquals(0.toShort(), response.bolusPulsesRemaining)
Assert.assertFalse(response.occlusionAlertActive) Assert.assertEquals(0, response.activeAlerts.size)
Assert.assertFalse(response.alert1Active)
Assert.assertFalse(response.alert2Active)
Assert.assertFalse(response.alert3Active)
Assert.assertFalse(response.alert4Active)
Assert.assertFalse(response.alert5Active)
Assert.assertFalse(response.alert6Active)
Assert.assertFalse(response.alert7Active)
Assert.assertEquals(280.toShort(), response.minutesSinceActivation) Assert.assertEquals(280.toShort(), response.minutesSinceActivation)
Assert.assertEquals(1023.toShort(), response.reservoirPulsesRemaining) Assert.assertEquals(1023.toShort(), response.reservoirPulsesRemaining)
} }