Initial TBR implementation and pumpSync for basals etc
This commit is contained in:
parent
61e873dbcc
commit
0d8f07ad0a
19 changed files with 622 additions and 104 deletions
|
@ -18,6 +18,7 @@ import info.nightscout.interfaces.pump.Pump
|
|||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
import info.nightscout.interfaces.pump.PumpPluginBase
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.interfaces.pump.actions.CustomAction
|
||||
import info.nightscout.interfaces.pump.actions.CustomActionType
|
||||
import info.nightscout.interfaces.pump.defs.ManufacturerType
|
||||
|
@ -51,6 +52,7 @@ import org.json.JSONException
|
|||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.round
|
||||
|
||||
@Singleton class MedtrumPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
|
@ -63,10 +65,11 @@ import javax.inject.Singleton
|
|||
private val context: Context,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val dateUtil: DateUtil,
|
||||
private val pumpSync: PumpSync,
|
||||
private val medtrumPump: MedtrumPump,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val profileFunction: ProfileFunction
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val pumpSync: PumpSync,
|
||||
private val temporaryBasalStorage: TemporaryBasalStorage
|
||||
) : PumpPluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.PUMP)
|
||||
|
@ -205,7 +208,7 @@ import javax.inject.Singleton
|
|||
}
|
||||
|
||||
override val baseBasalRate: Double
|
||||
get() = 0.0 // TODO
|
||||
get() = medtrumPump.baseBasalRate
|
||||
|
||||
override val reservoirLevel: Double
|
||||
get() = medtrumPump.reservoir
|
||||
|
@ -222,7 +225,24 @@ import javax.inject.Singleton
|
|||
}
|
||||
|
||||
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||
return PumpEnactResult(injector) // TODO
|
||||
if (!isInitialized()) return PumpEnactResult(injector).success(false).enacted(false)
|
||||
|
||||
aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - absoluteRate: $absoluteRate, durationInMinutes: $durationInMinutes, enforceNew: $enforceNew")
|
||||
// round rate to 0.05
|
||||
val pumpRate = round(absoluteRate * 20) / 20 // TODO: Maybe replace by constraints thing
|
||||
temporaryBasalStorage.add(PumpSync.PumpState.TemporaryBasal(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), pumpRate, true, tbrType, 0L, 0L))
|
||||
val connectionOk = medtrumService?.setTempBasal(pumpRate, durationInMinutes) ?: false
|
||||
if (connectionOk
|
||||
&& medtrumPump.tempBasalInProgress
|
||||
&& Math.abs(medtrumPump.tempBasalAbsoluteRate - pumpRate) <= 0.05
|
||||
/*&& Math.abs(medtrumPump.tempBasalRemainingMinutes - durationInMinutes) <= 5*/) {
|
||||
|
||||
return PumpEnactResult(injector).success(true).enacted(true).duration(/*medtrumPump.tempBasalRemainingMinutes*/durationInMinutes).absolute(medtrumPump.tempBasalAbsoluteRate).isPercent(false)
|
||||
.isTempCancel(false)
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMP, "setTempBasalAbsolute failed, connectionOk: $connectionOk, tempBasalInProgress: ${medtrumPump.tempBasalInProgress}, tempBasalAbsoluteRate: ${medtrumPump.tempBasalAbsoluteRate}") //, tempBasalRemainingMinutes: ${medtrumPump.tempBasalRemainingMinutes}")
|
||||
return PumpEnactResult(injector).success(false).enacted(false).comment("Medtrum setTempBasalAbsolute failed")
|
||||
}
|
||||
}
|
||||
|
||||
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||
|
@ -236,7 +256,16 @@ import javax.inject.Singleton
|
|||
}
|
||||
|
||||
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
||||
return PumpEnactResult(injector) // TODO
|
||||
if (!isInitialized()) return PumpEnactResult(injector).success(false).enacted(false)
|
||||
|
||||
aapsLogger.info(LTag.PUMP, "cancelTempBasal - enforceNew: $enforceNew")
|
||||
val connectionOk = medtrumService?.cancelTempBasal() ?: false
|
||||
if (connectionOk && !medtrumPump.tempBasalInProgress) {
|
||||
return PumpEnactResult(injector).success(true).enacted(true).isTempCancel(true)
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMP, "cancelTempBasal failed, connectionOk: $connectionOk, tempBasalInProgress: ${medtrumPump.tempBasalInProgress}")
|
||||
return PumpEnactResult(injector).success(false).enacted(false).comment("Medtrum cancelTempBasal failed")
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancelExtendedBolus(): PumpEnactResult {
|
||||
|
@ -289,8 +318,4 @@ import javax.inject.Singleton
|
|||
|
||||
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {
|
||||
}
|
||||
|
||||
private fun readTBR(): PumpSync.PumpState.TemporaryBasal? {
|
||||
return pumpSync.expectedPumpState().temporaryBasal // TODO
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
package info.nightscout.pump.medtrum
|
||||
|
||||
import android.util.Base64
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.interfaces.pump.defs.PumpType
|
||||
import info.nightscout.pump.medtrum.code.ConnectionState
|
||||
import info.nightscout.pump.medtrum.comm.enums.AlarmSetting
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import javax.inject.Inject
|
||||
|
@ -21,7 +27,9 @@ import kotlin.math.round
|
|||
class MedtrumPump @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val sp: SP,
|
||||
private val dateUtil: DateUtil
|
||||
private val dateUtil: DateUtil,
|
||||
private val pumpSync: PumpSync,
|
||||
private val temporaryBasalStorage: TemporaryBasalStorage
|
||||
) {
|
||||
|
||||
// Connection state flow
|
||||
|
@ -33,6 +41,14 @@ class MedtrumPump @Inject constructor(
|
|||
_connectionState.value = value
|
||||
}
|
||||
|
||||
/** Patch activated state, mainly for UI, but also controls the connection flow,
|
||||
* if patch is not activated, AAPS cannot connect to the pump, we can then connect trough the activation flow.
|
||||
* Note: this is also saved in SP, by the set functions
|
||||
*/
|
||||
private var _patchActivated = false
|
||||
val patchActivated: Boolean
|
||||
get() = _patchActivated
|
||||
|
||||
// Pump state flow
|
||||
private val _pumpState = MutableStateFlow(MedtrumPumpState.NONE)
|
||||
val pumpStateFlow: StateFlow<MedtrumPumpState> = _pumpState
|
||||
|
@ -42,10 +58,6 @@ class MedtrumPump @Inject constructor(
|
|||
_pumpState.value = value
|
||||
}
|
||||
|
||||
var _patchActivated = false
|
||||
val patchActivated: Boolean
|
||||
get() = _patchActivated
|
||||
|
||||
// Prime progress as state flow
|
||||
private val _primeProgress = MutableStateFlow(0)
|
||||
val primeProgressFlow: StateFlow<Int> = _primeProgress
|
||||
|
@ -55,14 +67,62 @@ class MedtrumPump @Inject constructor(
|
|||
_primeProgress.value = value
|
||||
}
|
||||
|
||||
var pumpSN = 0L
|
||||
val pumpType: PumpType = PumpType.MEDTRUM_NANO // TODO, type based on pumpSN or pump activation/connection
|
||||
var patchSessionToken = 0L
|
||||
/** Stuff stored in SP */
|
||||
private var _patchSessionToken = 0L
|
||||
var patchSessionToken: Long
|
||||
get() = _patchSessionToken
|
||||
set(value) {
|
||||
_patchSessionToken = value
|
||||
sp.putLong(R.string.key_session_token, value)
|
||||
}
|
||||
|
||||
private var _patchId = 0L
|
||||
var patchId: Long
|
||||
get() = _patchId
|
||||
set(value) {
|
||||
_patchId = value
|
||||
sp.putLong(R.string.key_patch_id, value)
|
||||
}
|
||||
|
||||
private var _currentSequenceNumber = 0
|
||||
var currentSequenceNumber: Int
|
||||
get() = _currentSequenceNumber
|
||||
set(value) {
|
||||
_currentSequenceNumber = value
|
||||
sp.putInt(R.string.key_current_sequence_number, value)
|
||||
}
|
||||
|
||||
private var _syncedSequenceNumber = 0
|
||||
var syncedSequenceNumber: Int
|
||||
get() = _syncedSequenceNumber
|
||||
set(value) {
|
||||
_syncedSequenceNumber = value
|
||||
sp.putInt(R.string.key_synced_sequence_number, value)
|
||||
}
|
||||
|
||||
private var _actualBasalProfile = byteArrayOf(0)
|
||||
var actualBasalProfile: ByteArray
|
||||
get() = _actualBasalProfile
|
||||
set(value) {
|
||||
_actualBasalProfile = value
|
||||
val encodedString = Base64.encodeToString(value, Base64.DEFAULT)
|
||||
sp.putString(R.string.key_actual_basal_profile, encodedString)
|
||||
}
|
||||
|
||||
private var _lastBasalType: BasalType = BasalType.NONE
|
||||
var lastBasalType: BasalType
|
||||
get() = _lastBasalType
|
||||
set(value) {
|
||||
_lastBasalType = value
|
||||
sp.putInt(R.string.key_last_basal_type, value.ordinal)
|
||||
}
|
||||
|
||||
private var _pumpSN = 0L
|
||||
val pumpSN: Long
|
||||
get() = _pumpSN
|
||||
|
||||
val pumpType: PumpType = PumpType.MEDTRUM_NANO // TODO, type based on pumpSN or pump activation/connection
|
||||
|
||||
// TODO: Save this in SP? This might be a bit tricky as we only know what we have set, not what the pump has set but the pump should not change it, addtionally we should track the active basal profile in pump e.g. Basal patern A, B etc
|
||||
var actualBasalProfile = byteArrayOf(0)
|
||||
var patchId = 0L
|
||||
var lastKnownSequenceNumber = 0
|
||||
var lastTimeReceivedFromPump = 0L // Time in seconds!
|
||||
var suspendTime = 0L // Time in seconds!
|
||||
var patchStartTime = 0L // Time in seconds!
|
||||
|
@ -77,15 +137,24 @@ class MedtrumPump @Inject constructor(
|
|||
var alarmParameter = 0
|
||||
|
||||
// Last basal status update
|
||||
var lastBasalType = 0
|
||||
// TODO: Save this in SP?
|
||||
var lastBasalRate = 0.0
|
||||
var lastBasalSequence = 0
|
||||
var lastBasalPatchId = 0
|
||||
var lastBasalPatchId = 0L
|
||||
var lastBasalStartTime = 0L
|
||||
|
||||
val baseBasalRate: Double
|
||||
get() = getCurrentHourlyBasalFromMedtrumProfileArray(actualBasalProfile)
|
||||
|
||||
// TBR status
|
||||
val tempBasalInProgress: Boolean
|
||||
get() = lastBasalType == BasalType.ABSOLUTE_TEMP || lastBasalType == BasalType.RELATIVE_TEMP
|
||||
val tempBasalAbsoluteRate: Double
|
||||
get() = if (tempBasalInProgress) lastBasalRate else 0.0
|
||||
|
||||
// Last stop status update
|
||||
var lastStopSequence = 0
|
||||
var lastStopPatchId = 0
|
||||
var lastStopPatchId = 0L
|
||||
|
||||
// TODO set these setting on init
|
||||
// User settings (desired values, to be set on pump)
|
||||
|
@ -94,6 +163,45 @@ class MedtrumPump @Inject constructor(
|
|||
var desiredHourlyMaxInsulin: Int = 40
|
||||
var desiredDailyMaxInsulin: Int = 180
|
||||
|
||||
init {
|
||||
// Load stuff from SP
|
||||
_patchActivated = sp.getBoolean(R.string.key_patch_activated, false)
|
||||
_patchSessionToken = sp.getLong(R.string.key_session_token, 0L)
|
||||
_currentSequenceNumber = sp.getInt(R.string.key_current_sequence_number, 0)
|
||||
_patchId = sp.getLong(R.string.key_patch_id, 0L)
|
||||
_syncedSequenceNumber = sp.getInt(R.string.key_synced_sequence_number, 0)
|
||||
_lastBasalType = enumValues<BasalType>()[sp.getInt(R.string.key_last_basal_type, 0)]
|
||||
|
||||
val encodedString = sp.getString(R.string.key_actual_basal_profile, "0")
|
||||
try {
|
||||
_actualBasalProfile = Base64.decode(encodedString, Base64.DEFAULT)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.PUMP, "Error decoding basal profile from SP: $encodedString")
|
||||
}
|
||||
|
||||
if (patchActivated) {
|
||||
aapsLogger.debug(LTag.PUMP, "changePump: Patch is already activated, setting as ACTIVE")
|
||||
// Set inital status as active will be updated on first connection
|
||||
pumpState = MedtrumPumpState.ACTIVE
|
||||
}
|
||||
|
||||
loadUserSettingsFromSP()
|
||||
}
|
||||
|
||||
fun loadUserSettingsFromSP() {
|
||||
// TODO
|
||||
// desiredPatchExpiration = sp.getBoolean(R.string.key_patch_expiration, false)
|
||||
// desiredAlarmSetting = sp.getInt(R.string.key_alarm_setting, AlarmSetting.LIGHT_VIBRATE_AND_BEEP.code)
|
||||
// desiredHourlyMaxInsulin = sp.getInt(R.string.key_hourly_max_insulin, 40)
|
||||
// desiredDailyMaxInsulin = sp.getInt(R.string.key_daily_max_insulin, 180)
|
||||
|
||||
try {
|
||||
_pumpSN = sp.getString(info.nightscout.pump.medtrum.R.string.key_snInput, " ").toLong(radix = 16)
|
||||
} catch (e: NumberFormatException) {
|
||||
aapsLogger.debug(LTag.PUMP, "changePump: Invalid input!")
|
||||
}
|
||||
}
|
||||
|
||||
fun setPatchActivatedState(activated: Boolean) {
|
||||
aapsLogger.debug(LTag.PUMP, "setPatchActivatedState: $activated")
|
||||
_patchActivated = activated
|
||||
|
@ -101,7 +209,8 @@ class MedtrumPump @Inject constructor(
|
|||
}
|
||||
|
||||
/** When the activation/deactivation screen, and the connection flow needs to be controlled,
|
||||
* this can be used to set the ActivatedState without saving to SP, So when app is force closed the state is still maintained */
|
||||
* this can be used to set the ActivatedState without saving to SP, So when app is force closed the state is still maintained
|
||||
*/
|
||||
fun setPatchActivatedStateTemp(activated: Boolean) {
|
||||
aapsLogger.debug(LTag.PUMP, "setPatchActivatedStateTemp: $activated")
|
||||
_patchActivated = activated
|
||||
|
@ -123,29 +232,109 @@ class MedtrumPump @Inject constructor(
|
|||
return (list.size).toByteArray(1) + basals
|
||||
}
|
||||
|
||||
fun handleBasalStatusUpdate(basalType: Int, basalValue: Double, basalSequence: Int, basalPatchId: Int, basalStartTime: Long) {
|
||||
fun getCurrentHourlyBasalFromMedtrumProfileArray(basalProfile: ByteArray): Double {
|
||||
val basalCount = basalProfile[0].toInt()
|
||||
var basal = 0.0
|
||||
if (basalProfile.size < 4 || (basalProfile.size - 1) % 3 != 0 || basalCount > 24) {
|
||||
aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: No valid basal profile set")
|
||||
return basal
|
||||
}
|
||||
|
||||
val hourOfDayMinutes = dateUtil.dateAndTimeString(dateUtil.now()).substring(11, 13).toInt() * 60 + dateUtil.dateAndTimeString(dateUtil.now()).substring(14, 16).toInt()
|
||||
|
||||
for (index in 0 until basalCount) {
|
||||
val currentIndex = 1 + (index * 3)
|
||||
val nextIndex = currentIndex + 3
|
||||
val rateAndTime = basalProfile.copyOfRange(currentIndex, nextIndex).toInt()
|
||||
val rate = (rateAndTime shr 12) * 0.05
|
||||
val startMinutes = rateAndTime and 0xFFF
|
||||
|
||||
val endMinutes = if (nextIndex < basalProfile.size) {
|
||||
val nextRateAndTime = basalProfile.copyOfRange(nextIndex, nextIndex + 3).toInt()
|
||||
nextRateAndTime and 0xFFF
|
||||
} else {
|
||||
24 * 60
|
||||
}
|
||||
|
||||
if (hourOfDayMinutes in startMinutes until endMinutes) {
|
||||
basal = rate
|
||||
aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: basal: $basal")
|
||||
break
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: rate: $rate, startMinutes: $startMinutes, endMinutes: $endMinutes")
|
||||
}
|
||||
return basal
|
||||
}
|
||||
|
||||
fun handleBasalStatusUpdate(basalType: BasalType, basalValue: Double, basalSequence: Int, basalPatchId: Long, basalStartTime: Long) {
|
||||
handleBasalStatusUpdate(basalType, basalValue, basalSequence, basalPatchId, basalStartTime, dateUtil.now())
|
||||
}
|
||||
|
||||
fun handleBasalStatusUpdate(basalType: Int, basalRate: Double, basalSequence: Int, basalPatchId: Int, basalStartTime: Long, receivedTime: Long) {
|
||||
fun handleBasalStatusUpdate(basalType: BasalType, basalRate: Double, basalSequence: Int, basalPatchId: Long, basalStartTime: Long, receivedTime: Long) {
|
||||
aapsLogger.debug(
|
||||
LTag.PUMP, "handleBasalStatusUpdate: basalType: $basalType basalValue: $basalRate basalSequence: $basalSequence basalPatchId: $basalPatchId basalStartTime: $basalStartTime " +
|
||||
"receivedTime: $receivedTime"
|
||||
LTag.PUMP,
|
||||
"handleBasalStatusUpdate: basalType: $basalType basalValue: $basalRate basalSequence: $basalSequence basalPatchId: $basalPatchId basalStartTime: $basalStartTime " + "receivedTime: $receivedTime"
|
||||
)
|
||||
if (basalType.isTempBasal()) {
|
||||
// TODO: Is this the correct place to sync temporaryBasalInfo? Note: it will be removed after getting it once, So this would only apply when called in setTempBasalPacket, maybe first check if basal entry already exists and leave this here, then we can also let the onNotification stuff sync basal?
|
||||
val temporaryBasalInfo = temporaryBasalStorage.findTemporaryBasal(basalStartTime, basalRate)
|
||||
|
||||
// If duration is unknown, no way to get it now, set patch lifetime as duration
|
||||
val duration = temporaryBasalInfo?.duration ?: T.mins(4800).msecs()
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = basalRate, // TODO: Support percent here, this will break things? Check if this is correct
|
||||
duration = duration,
|
||||
isAbsolute = (basalType == BasalType.ABSOLUTE_TEMP),
|
||||
type = temporaryBasalInfo?.type,
|
||||
pumpId = basalStartTime,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + "Rate: $basalRate Duration: ${duration}min"
|
||||
)
|
||||
} else if (basalType.isSuspendedByPump()) {
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = 0.0,
|
||||
duration = T.mins(4800).msecs(), // TODO MAGIC NUMBER
|
||||
isAbsolute = true,
|
||||
type = PumpSync.TemporaryBasalType.PUMP_SUSPEND,
|
||||
pumpId = basalStartTime,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_END ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime)"
|
||||
)
|
||||
}
|
||||
|
||||
// Update medtrum pump state
|
||||
lastBasalType = basalType
|
||||
lastBasalRate = basalRate
|
||||
lastBasalSequence = basalSequence
|
||||
lastKnownSequenceNumber = basalSequence
|
||||
if (basalSequence > currentSequenceNumber) {
|
||||
currentSequenceNumber = basalSequence
|
||||
}
|
||||
lastBasalPatchId = basalPatchId
|
||||
if (basalPatchId != patchId) {
|
||||
aapsLogger.error(LTag.PUMP, "handleBasalStatusUpdate: WTF? PatchId in status update does not match current patchId!")
|
||||
}
|
||||
lastBasalStartTime = basalStartTime
|
||||
// TODO Handle history
|
||||
}
|
||||
|
||||
fun handleStopStatusUpdate(stopSequence: Int, stopPatchId: Int) {
|
||||
fun handleStopStatusUpdate(stopSequence: Int, stopPatchId: Long) {
|
||||
aapsLogger.debug(LTag.PUMP, "handleStopStatusUpdate: stopSequence: $stopSequence stopPatchId: $stopPatchId")
|
||||
lastStopSequence = stopSequence
|
||||
lastKnownSequenceNumber = stopSequence
|
||||
if (stopSequence > currentSequenceNumber) {
|
||||
currentSequenceNumber = stopSequence
|
||||
}
|
||||
lastStopPatchId = stopPatchId
|
||||
// TODO Handle history
|
||||
if (stopPatchId != patchId) {
|
||||
aapsLogger.error(LTag.PUMP, "handleStopStatusUpdate: WTF? PatchId in status update does not match current patchId!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package info.nightscout.pump.medtrum.comm.enums
|
||||
|
||||
enum class BasalType {
|
||||
NONE,
|
||||
STANDARD,
|
||||
EXERCISE,
|
||||
HOLIDAY,
|
||||
PROGRAM_A,
|
||||
PROGRAM_B,
|
||||
ABSOLUTE_TEMP,
|
||||
RELATIVE_TEMP,
|
||||
PROGRAM_C,
|
||||
PROGRAM_D,
|
||||
SICK,
|
||||
AUTO,
|
||||
NEW,
|
||||
SUSPEND_LOW_GLUCOSE,
|
||||
SUSPEND_PREDICT_LOW_GLUCOSE,
|
||||
SUSPEND_AUTO,
|
||||
SUSPEND_MORE_THAN_MAX_PER_HOUR,
|
||||
SUSPEND_MORE_THAN_MAX_PER_DAY,
|
||||
SUSPEND_MANUAL,
|
||||
SUSPEND_KEY_LOST,
|
||||
STOP_OCCLUSION,
|
||||
STOP_EXPIRED,
|
||||
STOP_EMPTY,
|
||||
STOP_PATCH_FAULT,
|
||||
STOP_PATCH_FAULT2,
|
||||
STOP_BASE_FAULT,
|
||||
STOP_DISCARD,
|
||||
STOP_BATTERY_EXHAUSTED,
|
||||
STOP,
|
||||
PAUSE_INTERRUPT,
|
||||
PRIME,
|
||||
AUTO_MODE_START,
|
||||
AUTO_MODE_EXIT,
|
||||
AUTO_MODE_TARGET_100,
|
||||
AUTO_MODE_TARGET_110,
|
||||
AUTO_MODE_TARGET_120,
|
||||
AUTO_MODE_BREAKFAST,
|
||||
AUTO_MODE_LUNCH,
|
||||
AUTO_MODE_DINNER,
|
||||
AUTO_MODE_SNACK,
|
||||
AUTO_MODE_EXERCISE_START,
|
||||
AUTO_MODE_EXERCISE_EXIT;
|
||||
|
||||
fun getValue(): Int {
|
||||
return ordinal
|
||||
}
|
||||
|
||||
fun isTempBasal(): Boolean {
|
||||
return this == ABSOLUTE_TEMP || this == RELATIVE_TEMP
|
||||
}
|
||||
|
||||
fun isSuspendedByPump(): Boolean {
|
||||
return this in SUSPEND_LOW_GLUCOSE..STOP
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import info.nightscout.interfaces.pump.DetailedBolusInfo
|
|||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.ACTIVATE
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import info.nightscout.pump.medtrum.extension.toByte
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
|
@ -85,15 +86,17 @@ class ActivatePacket(injector: HasAndroidInjector, private val basalProfile: Byt
|
|||
val medtrumTimeUtil = MedtrumTimeUtil()
|
||||
|
||||
val patchId = data.copyOfRange(RESP_PATCH_ID_START, RESP_PATCH_ID_END).toLong()
|
||||
val time = medtrumTimeUtil.convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_TIME_START, RESP_TIME_END).toLong())
|
||||
val basalType = data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()
|
||||
val time = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_TIME_START, RESP_TIME_END).toLong())
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()]
|
||||
val basalValue = data.copyOfRange(RESP_BASAL_VALUE_START, RESP_BASAL_VALUE_END).toInt() * 0.05
|
||||
val basalSequence = data.copyOfRange(RESP_BASAL_SEQUENCE_START, RESP_BASAL_SEQUENCE_END).toInt()
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toInt()
|
||||
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toLong()
|
||||
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
|
||||
medtrumPump.patchId = patchId
|
||||
medtrumPump.lastTimeReceivedFromPump = time
|
||||
medtrumPump.currentSequenceNumber = basalSequence // We are activated, set the new seq nr
|
||||
medtrumPump.syncedSequenceNumber = basalSequence // We are activated, reset the synced seq nr ()
|
||||
// Update the actual basal profile
|
||||
medtrumPump.actualBasalProfile = basalProfile
|
||||
// TODO: Handle history entry
|
||||
|
|
|
@ -3,9 +3,11 @@ package info.nightscout.pump.medtrum.comm.packets
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.CANCEL_TEMP_BASAL
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.pump.medtrum.extension.toLong
|
||||
import info.nightscout.pump.medtrum.util.MedtrumTimeUtil
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import javax.inject.Inject
|
||||
|
||||
class CancelTempBasalPacket(injector: HasAndroidInjector) : MedtrumPacket(injector) {
|
||||
|
@ -34,11 +36,11 @@ class CancelTempBasalPacket(injector: HasAndroidInjector) : MedtrumPacket(inject
|
|||
override fun handleResponse(data: ByteArray): Boolean {
|
||||
val success = super.handleResponse(data)
|
||||
if (success) {
|
||||
val basalType = data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()]
|
||||
val basalRate = data.copyOfRange(RESP_BASAL_RATE_START, RESP_BASAL_RATE_END).toInt() * 0.05
|
||||
val basalSequence = data.copyOfRange(RESP_BASAL_SEQUENCE_START, RESP_BASAL_SEQUENCE_END).toInt()
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toInt()
|
||||
val basalStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toLong()
|
||||
val basalStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
|
||||
medtrumPump.handleBasalStatusUpdate(basalType, basalRate, basalSequence, basalPatchId, basalStartTime)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
package info.nightscout.pump.medtrum.comm.packets
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.GET_RECORD
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.pump.medtrum.extension.toLong
|
||||
import info.nightscout.pump.medtrum.util.MedtrumTimeUtil
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int) : MedtrumPacket(injector) {
|
||||
|
||||
@Inject lateinit var medtrumPump: MedtrumPump
|
||||
@Inject lateinit var pumpSync: PumpSync
|
||||
@Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -20,11 +30,29 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
|
|||
private const val RESP_RECORD_UNKNOWN_END = RESP_RECORD_UNKNOWN_START + 1
|
||||
private const val RESP_RECORD_TYPE_START = RESP_RECORD_UNKNOWN_END
|
||||
private const val RESP_RECORD_TYPE_END = RESP_RECORD_TYPE_START + 1
|
||||
private const val RESP_RECORD_SERIAL_START = RESP_RECORD_TYPE_END
|
||||
private const val RESP_RECORD_UNKNOWN1_START = RESP_RECORD_TYPE_END
|
||||
private const val RESP_RECORD_UNKNOWN1_END = RESP_RECORD_UNKNOWN1_START + 1
|
||||
private const val RESP_RECORD_SERIAL_START = RESP_RECORD_UNKNOWN1_END
|
||||
private const val RESP_RECORD_SERIAL_END = RESP_RECORD_SERIAL_START + 4
|
||||
private const val RESP_RECORD_PATCHID_START = RESP_RECORD_SERIAL_END
|
||||
private const val RESP_RECORD_PATCHID_END = RESP_RECORD_PATCHID_START + 2
|
||||
private const val RESP_RECORD_DATA_START = RESP_RECORD_PATCHID_END
|
||||
private const val RESP_RECORD_SEQUENCE_START = RESP_RECORD_PATCHID_END
|
||||
private const val RESP_RECORD_SEQUENCE_END = RESP_RECORD_SEQUENCE_START + 2
|
||||
private const val RESP_RECORD_DATA_START = RESP_RECORD_SEQUENCE_END
|
||||
|
||||
private const val VALID_HEADER = 170
|
||||
private const val BOLUS_RECORD = 1
|
||||
private const val BOLUS_RECORD_ALT = 65
|
||||
private const val BASAL_RECORD = 2
|
||||
private const val BASAL_RECORD_ALT = 66
|
||||
private const val ALARM_RECORD = 3
|
||||
private const val AUTO_RECORD = 4
|
||||
private const val TIME_SYNC_RECORD = 5
|
||||
private const val AUTO1_RECORD = 6
|
||||
private const val AUTO2_RECORD = 7
|
||||
private const val AUTO3_RECORD = 8
|
||||
private const val TDD_RECORD = 9
|
||||
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -44,8 +72,137 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
|
|||
val recordType = data.copyOfRange(RESP_RECORD_TYPE_START, RESP_RECORD_TYPE_END).toInt()
|
||||
val recordSerial = data.copyOfRange(RESP_RECORD_SERIAL_START, RESP_RECORD_SERIAL_END).toLong()
|
||||
val recordPatchId = data.copyOfRange(RESP_RECORD_PATCHID_START, RESP_RECORD_PATCHID_END).toInt()
|
||||
val recordSequence = data.copyOfRange(RESP_RECORD_SEQUENCE_START, RESP_RECORD_SEQUENCE_END).toInt()
|
||||
|
||||
// TODO Handle history records
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"GetRecordPacket HandleResponse: Record header: $recordHeader, unknown: $recordUnknown, type: $recordType, serial: $recordSerial, patchId: $recordPatchId, " + "sequence: $recordSequence"
|
||||
)
|
||||
|
||||
medtrumPump.syncedSequenceNumber = recordSequence // Assume sync upwards
|
||||
|
||||
if (recordHeader == VALID_HEADER) {
|
||||
when (recordType) {
|
||||
BOLUS_RECORD, BOLUS_RECORD_ALT -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD")
|
||||
}
|
||||
|
||||
BASAL_RECORD, BASAL_RECORD_ALT -> {
|
||||
val medtrumTimeUtil = MedtrumTimeUtil()
|
||||
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_RECORD_DATA_START, RESP_RECORD_DATA_START + 4).toLong())
|
||||
val basalEndTime = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_RECORD_DATA_START + 4, RESP_RECORD_DATA_START + 8).toLong())
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(RESP_RECORD_DATA_START + 8, RESP_RECORD_DATA_START + 9).toInt()]
|
||||
val basalEndReason = data.copyOfRange(RESP_RECORD_DATA_START + 9, RESP_RECORD_DATA_START + 10).toInt()
|
||||
val basalRate = data.copyOfRange(RESP_RECORD_DATA_START + 10, RESP_RECORD_DATA_START + 12).toInt() * 0.05
|
||||
val basalDelivered = data.copyOfRange(RESP_RECORD_DATA_START + 12, RESP_RECORD_DATA_START + 14).toInt() * 0.05
|
||||
val basalPercent = data.copyOfRange(RESP_RECORD_DATA_START + 14, RESP_RECORD_DATA_START + 16).toInt()
|
||||
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"GetRecordPacket HandleResponse: BASAL_RECORD: Start: $basalStartTime, End: $basalEndTime, Type: $basalType, EndReason: $basalEndReason, Rate: $basalRate, Delivered: $basalDelivered, Percent: $basalPercent"
|
||||
)
|
||||
|
||||
when (basalType) {
|
||||
BasalType.STANDARD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BASAL_RECORD: Standard basal")
|
||||
// If we are here it means the basal has ended
|
||||
}
|
||||
|
||||
BasalType.ABSOLUTE_TEMP, BasalType.RELATIVE_TEMP -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BASAL_RECORD: Absolute temp basal")
|
||||
val duration = (basalEndTime - basalStartTime)
|
||||
if (duration > 0) { // Sync start and end
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = if (basalType == BasalType.ABSOLUTE_TEMP) basalRate else basalPercent.toDouble(),
|
||||
duration = duration,
|
||||
isAbsolute = (basalType == BasalType.ABSOLUTE_TEMP),
|
||||
type = PumpSync.TemporaryBasalType.NORMAL,
|
||||
pumpId = basalStartTime,
|
||||
pumpType = medtrumPump.pumpType,
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate from record: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_SYNC: ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " +
|
||||
"Rate: $basalRate Duration: ${duration}min"
|
||||
)
|
||||
} else { // Sync only end ?
|
||||
pumpSync.syncStopTemporaryBasalWithPumpId(
|
||||
timestamp = basalEndTime,
|
||||
endPumpId = basalEndTime,
|
||||
pumpType = medtrumPump.pumpType,
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.warn(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate from record: EVENT TEMP_END ($basalType) ${dateUtil.dateAndTimeString(basalEndTime)} ($basalEndTime) " + "Rate: $basalRate Duration: ${duration}min"
|
||||
)
|
||||
}
|
||||
}
|
||||
in BasalType.SUSPEND_LOW_GLUCOSE..BasalType.STOP -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BASAL_RECORD: Suspend basal")
|
||||
val duration = (basalEndTime - basalStartTime)
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalEndTime,
|
||||
rate = 0.0,
|
||||
duration = duration,
|
||||
isAbsolute = true,
|
||||
type = PumpSync.TemporaryBasalType.PUMP_SUSPEND,
|
||||
pumpId = basalStartTime,
|
||||
pumpType = medtrumPump.pumpType,
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate from record: ${if (newRecord) "**NEW** " else ""}EVENT SUSPEND: ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " +
|
||||
"Rate: $basalRate Duration: ${duration}min"
|
||||
)
|
||||
|
||||
}
|
||||
else -> {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BASAL_RECORD: Unknown basal type: $basalType")
|
||||
// TODO: Error warning
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALARM_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: ALARM_RECORD")
|
||||
}
|
||||
|
||||
AUTO_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: AUTO_RECORD")
|
||||
}
|
||||
|
||||
TIME_SYNC_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: TIME_SYNC_RECORD")
|
||||
}
|
||||
|
||||
AUTO1_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: AUTO1_RECORD")
|
||||
}
|
||||
|
||||
AUTO2_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: AUTO2_RECORD")
|
||||
}
|
||||
|
||||
AUTO3_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: AUTO3_RECORD")
|
||||
}
|
||||
|
||||
TDD_RECORD -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: TDD_RECORD")
|
||||
}
|
||||
|
||||
else -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: Unknown record type: $recordType")
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: Invalid record header")
|
||||
}
|
||||
}
|
||||
|
||||
return success
|
||||
|
|
|
@ -25,7 +25,7 @@ class GetTimePacket(injector: HasAndroidInjector) : MedtrumPacket(injector) {
|
|||
override fun handleResponse(data: ByteArray): Boolean {
|
||||
val success = super.handleResponse(data)
|
||||
if (success) {
|
||||
val time = MedtrumTimeUtil().convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_TIME_START, RESP_TIME_END).toLong())
|
||||
val time = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_TIME_START, RESP_TIME_END).toLong())
|
||||
medtrumPump.lastTimeReceivedFromPump = time
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.pump.medtrum.comm.packets
|
|||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
|
@ -98,7 +99,7 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
var bolusData = data.copyOfRange(offset, offset + 1).toInt()
|
||||
var bolusType = bolusData and 0x7F
|
||||
var bolusCompleted = (bolusData shr 7) and 0x01 // TODO: Check for other flags here :)
|
||||
var bolusDelivered = data.copyOfRange(offset + 1, offset + 3).toInt() / 0.05
|
||||
var bolusDelivered = data.copyOfRange(offset + 1, offset + 3).toInt() * 0.05
|
||||
// TODO Sync bolus flow:
|
||||
// If bolus is known add status
|
||||
// If bolus is not known start read bolus
|
||||
|
@ -115,18 +116,20 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
|
||||
if (fieldMask and MASK_BASAL != 0) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Basal notification received")
|
||||
var basalType = data.copyOfRange(offset, offset + 1).toInt()
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(offset, offset + 1).toInt()]
|
||||
var basalSequence = data.copyOfRange(offset + 1, offset + 3).toInt()
|
||||
var basalPatchId = data.copyOfRange(offset + 3, offset + 5).toInt()
|
||||
var basalInterval = data.copyOfRange(offset + 5, offset + 9).toInt()
|
||||
var basalPatchId = data.copyOfRange(offset + 3, offset + 5).toLong()
|
||||
var basalTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset + 5, offset + 9).toLong())
|
||||
var basalRateAndDelivery = data.copyOfRange(offset + 9, offset + 12).toInt()
|
||||
var basalRate = (basalRateAndDelivery and 0xFFF) * 0.05
|
||||
var basalDelivery = (basalRateAndDelivery shr 12) * 0.05
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"Basal type: $basalType, basal sequence: $basalSequence, basal patch id: $basalPatchId, basal interval: $basalInterval, basal rate: $basalRate, basal delivery: $basalDelivery"
|
||||
"Basal type: $basalType, basal sequence: $basalSequence, basal patch id: $basalPatchId, basal time: $basalTime, basal rate: $basalRate, basal delivery: $basalDelivery"
|
||||
)
|
||||
// TODO Sync basal flow
|
||||
// TODO: Check if basal is known, if not add it
|
||||
// medtrumPump.handleBasalStatusUpdate(basalType, basalRate, basalSequence, basalPatchId, basalTime)
|
||||
// TODO: Handle basal delivery
|
||||
offset += 12
|
||||
}
|
||||
|
||||
|
@ -165,9 +168,16 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
if (fieldMask and MASK_STORAGE != 0) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Storage notification received")
|
||||
// TODO, trigger check for new sequence?
|
||||
medtrumPump.lastKnownSequenceNumber = data.copyOfRange(offset, offset + 2).toInt()
|
||||
medtrumPump.patchId = data.copyOfRange(offset + 2, offset + 4).toLong()
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Last known sequence number: ${medtrumPump.lastKnownSequenceNumber}, patch id: ${medtrumPump.patchId}")
|
||||
val sequence = data.copyOfRange(offset, offset + 2).toInt()
|
||||
if (sequence > medtrumPump.currentSequenceNumber) {
|
||||
medtrumPump.currentSequenceNumber = sequence
|
||||
}
|
||||
val patchId = data.copyOfRange(offset + 2, offset + 4).toLong()
|
||||
if (patchId != medtrumPump.patchId) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "handleMaskedMessage: WTF? We got wrong patch id!")
|
||||
// TODO: We should terminate session or stop patch here? or at least throw error? THis can be thrown during activation process though
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Last known sequence number: ${medtrumPump.currentSequenceNumber}, patch id: ${patchId}")
|
||||
offset += 4
|
||||
}
|
||||
|
||||
|
@ -182,7 +192,7 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
|
||||
if (fieldMask and MASK_START_TIME != 0) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Start time notification received")
|
||||
medtrumPump.patchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeSeconds(data.copyOfRange(offset, offset + 4).toLong())
|
||||
medtrumPump.patchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset, offset + 4).toLong())
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time: ${medtrumPump.patchStartTime}")
|
||||
offset += 4
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.pump.medtrum.comm.packets
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.SET_BASAL_PROFILE
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.pump.medtrum.extension.toLong
|
||||
import info.nightscout.pump.medtrum.util.MedtrumTimeUtil
|
||||
|
@ -41,11 +42,11 @@ class SetBasalProfilePacket(injector: HasAndroidInjector, private val basalProfi
|
|||
val success = super.handleResponse(data)
|
||||
if (success) {
|
||||
val medtrumTimeUtil = MedtrumTimeUtil()
|
||||
val basalType = data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()]
|
||||
val basalValue = data.copyOfRange(RESP_BASAL_VALUE_START, RESP_BASAL_VALUE_END).toInt() * 0.05
|
||||
val basalSequence = data.copyOfRange(RESP_BASAL_SEQUENCE_START, RESP_BASAL_SEQUENCE_END).toInt()
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toInt()
|
||||
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toLong()
|
||||
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
|
||||
// Update the actual basal profile
|
||||
medtrumPump.actualBasalProfile = basalProfile
|
||||
|
|
|
@ -3,10 +3,12 @@ package info.nightscout.pump.medtrum.comm.packets
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.SET_TEMP_BASAL
|
||||
import info.nightscout.pump.medtrum.comm.enums.BasalType
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.pump.medtrum.extension.toLong
|
||||
import info.nightscout.pump.medtrum.util.MedtrumTimeUtil
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.round
|
||||
|
||||
|
@ -49,11 +51,19 @@ class SetTempBasalPacket(injector: HasAndroidInjector, private val absoluteRate:
|
|||
override fun handleResponse(data: ByteArray): Boolean {
|
||||
val success = super.handleResponse(data)
|
||||
if (success) {
|
||||
val basalType = data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()
|
||||
val basalType = enumValues<BasalType>()[data.copyOfRange(RESP_BASAL_TYPE_START, RESP_BASAL_TYPE_END).toInt()]
|
||||
val basalRate = data.copyOfRange(RESP_BASAL_RATE_START, RESP_BASAL_RATE_END).toInt() * 0.05
|
||||
val basalSequence = data.copyOfRange(RESP_BASAL_SEQUENCE_START, RESP_BASAL_SEQUENCE_END).toInt()
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toInt()
|
||||
val basalStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeSeconds(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
val basalPatchId = data.copyOfRange(RESP_BASAL_PATCH_ID_START, RESP_BASAL_PATCH_ID_END).toLong()
|
||||
|
||||
val rawTime = data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong()
|
||||
val basalStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Basal status update: type=$basalType, rate=$basalRate, sequence=$basalSequence, patchId=$basalPatchId, startTime=$basalStartTime, rawTime=$rawTime")
|
||||
|
||||
// TODO: For debugging remove later
|
||||
val pumpTime = MedtrumTimeUtil().getCurrentTimePumpSeconds()
|
||||
val systemTime = System.currentTimeMillis()
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Pump time: $pumpTime, System time: $systemTime")
|
||||
|
||||
medtrumPump.handleBasalStatusUpdate(basalType, basalRate, basalSequence, basalPatchId, basalStartTime)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.extension.toInt
|
||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.STOP_PATCH
|
||||
import info.nightscout.pump.medtrum.extension.toLong
|
||||
import javax.inject.Inject
|
||||
|
||||
class StopPatchPacket(injector: HasAndroidInjector) : MedtrumPacket(injector) {
|
||||
|
@ -27,7 +28,7 @@ class StopPatchPacket(injector: HasAndroidInjector) : MedtrumPacket(injector) {
|
|||
val success = super.handleResponse(data)
|
||||
if (success) {
|
||||
val stopSequence = data.copyOfRange(RESP_STOP_SEQUENCE_START, RESP_STOP_SEQUENCE_END).toInt()
|
||||
val stopPatchId = data.copyOfRange(RESP_STOP_PATCH_ID_START, RESP_STOP_PATCH_ID_END).toInt()
|
||||
val stopPatchId = data.copyOfRange(RESP_STOP_PATCH_ID_START, RESP_STOP_PATCH_ID_END).toLong()
|
||||
|
||||
medtrumPump.handleStopStatusUpdate(stopSequence, stopPatchId)
|
||||
}
|
||||
|
|
|
@ -116,8 +116,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
}
|
||||
|
||||
fun startPrime(): Boolean {
|
||||
val packet = PrimePacket(injector)
|
||||
return sendPacketAndGetResponse(packet)
|
||||
return sendPacketAndGetResponse(PrimePacket(injector))
|
||||
}
|
||||
|
||||
fun startActivate(): Boolean {
|
||||
|
@ -141,18 +140,19 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
}
|
||||
|
||||
fun readPumpStatus() {
|
||||
// TODO read pump history
|
||||
}
|
||||
// TODO decide what we need to do here
|
||||
var result = false
|
||||
|
||||
fun loadEvents(): PumpEnactResult {
|
||||
if (!medtrumPlugin.isInitialized()) {
|
||||
val result = PumpEnactResult(injector).success(false)
|
||||
result.comment = "pump not initialized"
|
||||
return result
|
||||
// Most of these things are already done when a connection is setup, but wo dont know how long the pump was connected for?
|
||||
// So just do a syncronize to make sure we have the latest data
|
||||
result = sendPacketAndGetResponse(SynchronizePacket(injector))
|
||||
|
||||
// Sync records (based on the info we have from the sync)
|
||||
if (result) result = syncRecords()
|
||||
if (!result) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Failed to sync records")
|
||||
return
|
||||
}
|
||||
// TODO need this? Check
|
||||
val result = PumpEnactResult(injector)
|
||||
return result
|
||||
}
|
||||
|
||||
fun bolus(insulin: Double, carbs: Int, carbTime: Long, t: EventOverviewBolusProgress.Treatment): Boolean {
|
||||
|
@ -165,24 +165,59 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
// TODO
|
||||
}
|
||||
|
||||
fun setTempBasal(absoluteRate: Double, durationInMinutes: Int): Boolean {
|
||||
var result = true
|
||||
if (medtrumPump.tempBasalInProgress) {
|
||||
result = sendPacketAndGetResponse(CancelTempBasalPacket(injector))
|
||||
}
|
||||
if (result) result = sendPacketAndGetResponse(SetTempBasalPacket(injector, absoluteRate, durationInMinutes))
|
||||
|
||||
// Get history records, this will update the pump state
|
||||
if (result) result = syncRecords()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun cancelTempBasal(): Boolean {
|
||||
var result = false
|
||||
|
||||
result = sendPacketAndGetResponse(CancelTempBasalPacket(injector))
|
||||
|
||||
// Get history records, this will update the pump state
|
||||
if (result) result = syncRecords()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun updateBasalsInPump(profile: Profile): Boolean {
|
||||
var result = false
|
||||
val packet = medtrumPump.buildMedtrumProfileArray(profile)?.let { SetBasalProfilePacket(injector, it) }
|
||||
return packet?.let { sendPacketAndGetResponse(it) } == true
|
||||
result = packet?.let { sendPacketAndGetResponse(it) } == true
|
||||
|
||||
// TODO: We might want to get rid of this and cancel the TBR before we set the basal profile
|
||||
// Update basal affects the TBR records (the pump will cancel the TBR, set our basal profile, and resume the TBR in a new record)
|
||||
// Get history records, this will update the pump state and add changes in TBR to AAPS history
|
||||
if (result) result = syncRecords()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun changePump() {
|
||||
aapsLogger.debug(LTag.PUMP, "changePump: called!")
|
||||
try {
|
||||
medtrumPump.pumpSN = sp.getString(info.nightscout.pump.medtrum.R.string.key_snInput, " ").toLong(radix = 16)
|
||||
} catch (e: NumberFormatException) {
|
||||
aapsLogger.debug(LTag.PUMP, "changePump: Invalid input!")
|
||||
medtrumPump.loadUserSettingsFromSP()
|
||||
}
|
||||
medtrumPump.setPatchActivatedState(sp.getBoolean(R.string.key_patch_activated, false))
|
||||
medtrumPump.patchSessionToken = sp.getLong(R.string.key_session_token, 0)
|
||||
if (medtrumPump.patchActivated) {
|
||||
aapsLogger.debug(LTag.PUMP, "changePump: Patch is already activated, setting as ACTIVE")
|
||||
medtrumPump.pumpState = MedtrumPumpState.ACTIVE // Set inital status as active will be updated on first connection
|
||||
|
||||
/** This gets the history records from the pump */
|
||||
private fun syncRecords(): Boolean {
|
||||
aapsLogger.debug(LTag.PUMP, "syncRecords: called!, syncedSequenceNumber: ${medtrumPump.syncedSequenceNumber}, currentSequenceNumber: ${medtrumPump.currentSequenceNumber}")
|
||||
var result = false
|
||||
// TODO: Check if we need to sync older records as well
|
||||
// Note: medtrum app fetches all records when they sync?
|
||||
for (sequence in medtrumPump.syncedSequenceNumber..medtrumPump.currentSequenceNumber) {
|
||||
result = sendPacketAndGetResponse(GetRecordPacket(injector, sequence))
|
||||
if (!result) break
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** BLECommCallbacks */
|
||||
|
@ -206,7 +241,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
|
||||
override fun onSendMessageError(reason: String) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< error during send message $reason")
|
||||
// TODO
|
||||
currentState.onSendMessageError(reason)
|
||||
}
|
||||
|
||||
/** Service stuff */
|
||||
|
@ -270,6 +305,10 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
open fun waitForResponse(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
open fun onSendMessageError(reason: String) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "onSendMessageError: " + this.toString() + "reason: $reason")
|
||||
}
|
||||
}
|
||||
|
||||
private inner class IdleState : State() {
|
||||
|
@ -350,16 +389,18 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
override fun onIndication(data: ByteArray) {
|
||||
if (mPacket?.handleResponse(data) == true) {
|
||||
// Succes!
|
||||
val currTimeSec = dateUtil.nowWithoutMilliseconds() / 1000
|
||||
if (abs(timeUtil.convertPumpTimeToSystemTimeSeconds(medtrumPump.lastTimeReceivedFromPump) - currTimeSec) <= 5) { // Allow 5 sec deviation
|
||||
val currTime = dateUtil.nowWithoutMilliseconds()
|
||||
if (abs(medtrumPump.lastTimeReceivedFromPump - currTime) <= T.secs(5).msecs()) { // Allow 5 sec deviation
|
||||
toState(SynchronizeState())
|
||||
} else {
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"GetTimeState.onIndication need to set time. systemTime: $currTimeSec PumpTime: ${medtrumPump.lastTimeReceivedFromPump} Pump Time to system time: " + timeUtil.convertPumpTimeToSystemTimeSeconds(
|
||||
"GetTimeState.onIndication need to set time. systemTime: $currTime PumpTime: ${medtrumPump.lastTimeReceivedFromPump} Pump Time to system time: " + timeUtil
|
||||
.convertPumpTimeToSystemTimeMillis(
|
||||
medtrumPump.lastTimeReceivedFromPump
|
||||
)
|
||||
)
|
||||
// TODO: Setting time cancels any TBR, so we need to handle that and cancel? or let AAPS handle time syncs?
|
||||
toState(SetTimeState())
|
||||
}
|
||||
} else if (mPacket?.failed == true) {
|
||||
|
@ -497,6 +538,12 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
responseSuccess = false
|
||||
}
|
||||
|
||||
override fun onSendMessageError(reason: String) {
|
||||
super.onSendMessageError(reason)
|
||||
responseHandled = true
|
||||
responseSuccess = false
|
||||
}
|
||||
|
||||
override fun waitForResponse(): Boolean {
|
||||
val startTime = System.currentTimeMillis()
|
||||
val timeoutMillis = T.secs(45).msecs()
|
||||
|
|
|
@ -46,9 +46,9 @@ class MedtrumOverviewFragment : MedtrumBaseFragment<FragmentMedtrumOverviewBindi
|
|||
EventType.ACTIVATION_CLICKED -> requireContext().apply {
|
||||
val step = convertToPatchStep(medtrumPump.pumpState)
|
||||
// TODO is stil needed?
|
||||
if (step != PatchStep.PREPARE_PATCH) {
|
||||
aapsLogger.warn(LTag.PUMP, "MedtrumOverviewFragment: Patch already in activation process, going to $step")
|
||||
}
|
||||
// if (step != PatchStep.PREPARE_PATCH) {
|
||||
// aapsLogger.warn(LTag.PUMP, "MedtrumOverviewFragment: Patch already in activation process, going to $step")
|
||||
// }
|
||||
startActivity(MedtrumActivity.createIntentFromMenu(this, step))
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,6 @@ class MedtrumViewModel @Inject constructor(
|
|||
// New session, generate new session token
|
||||
aapsLogger.info(LTag.PUMP, "preparePatch: new session")
|
||||
medtrumPump.patchSessionToken = Crypt().generateRandomToken()
|
||||
sp.putLong(R.string.key_session_token, medtrumPump.patchSessionToken)
|
||||
// Connect to pump
|
||||
medtrumService?.connect("PreparePatch")
|
||||
}
|
||||
|
|
|
@ -11,10 +11,16 @@ class MedtrumTimeUtil {
|
|||
return Duration.between(startInstant, currentInstant).seconds
|
||||
}
|
||||
|
||||
fun convertPumpTimeToSystemTimeSeconds(pumpTime: Long) : Long {
|
||||
fun getCurrentTimePumpMillis() : Long {
|
||||
val startInstant = Instant.parse("2014-01-01T00:00:00Z")
|
||||
val currentInstant = Instant.now()
|
||||
return Duration.between(startInstant, currentInstant).seconds * 1000
|
||||
}
|
||||
|
||||
fun convertPumpTimeToSystemTimeMillis(pumpTime: Long) : Long {
|
||||
val startInstant = Instant.parse("2014-01-01T00:00:00Z")
|
||||
val pumpInstant = startInstant.plusSeconds(pumpTime)
|
||||
val epochInstant = Instant.EPOCH
|
||||
return Duration.between(epochInstant, pumpInstant).seconds
|
||||
return Duration.between(epochInstant, pumpInstant).seconds * 1000
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
<string name="key_medtrumpump_settings" translatable="false">medtrumpump_settings</string>
|
||||
<string name="key_patch_activated" translatable="false">medtrum_patch_activated</string>
|
||||
<string name="key_session_token" translatable="false">medtrum_session_token</string>
|
||||
<string name="key_patch_id" translatable="false">patch_id</string>
|
||||
<string name="key_actual_basal_profile" translatable="false">actual_basal_profile</string>
|
||||
<string name="key_last_basal_type" translatable="false">last_basal_type</string>
|
||||
<string name="key_current_sequence_number" translatable="false">current_sequence_number</string>
|
||||
<string name="key_synced_sequence_number" translatable="false">synced_sequence_number</string>
|
||||
|
||||
<string name="medtrum">Medtrum</string>
|
||||
<string name="medtrum_pump_shortname">MEDTRUM</string>
|
||||
|
|
|
@ -4,6 +4,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
|
|||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.mockito.Mock
|
||||
|
@ -14,11 +15,12 @@ open class MedtrumTestBase: TestBaseWithProfile() {
|
|||
@Mock lateinit var instantiator: Instantiator
|
||||
@Mock lateinit var tddCalculator: TddCalculator
|
||||
@Mock lateinit var pumpSync: PumpSync
|
||||
@Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
||||
|
||||
lateinit var medtrumPump: MedtrumPump
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
medtrumPump = MedtrumPump(aapsLogger, sp, dateUtil)
|
||||
medtrumPump = MedtrumPump(aapsLogger, sp, dateUtil, pumpSync, temporaryBasalStorage)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.pump.medtrum.comm.packets
|
|||
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.MedtrumTestBase
|
||||
import info.nightscout.pump.medtrum.extension.toByteArray
|
||||
import org.junit.jupiter.api.Test
|
||||
|
@ -23,7 +24,9 @@ class AuthorizePacketTest : MedtrumTestBase() {
|
|||
@Test fun getRequestGivenPacketAndSNWhenCalledThenReturnAuthorizePacket() {
|
||||
// Inputs
|
||||
val opCode = 5
|
||||
medtrumPump.pumpSN = 2859923929
|
||||
val _pumpSN = MedtrumPump::class.java.getDeclaredField("_pumpSN")
|
||||
_pumpSN.isAccessible = true
|
||||
_pumpSN.setLong(medtrumPump, 2859923929)
|
||||
medtrumPump.patchSessionToken = 667
|
||||
|
||||
// Call
|
||||
|
|
|
@ -48,7 +48,7 @@ class GetTimePacketTest : MedtrumTestBase() {
|
|||
// Expected values
|
||||
assertEquals(true, result)
|
||||
assertEquals(false, packet.failed)
|
||||
assertEquals(MedtrumTimeUtil().convertPumpTimeToSystemTimeSeconds(time), medtrumPump.lastTimeReceivedFromPump)
|
||||
assertEquals(MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(time), medtrumPump.lastTimeReceivedFromPump)
|
||||
}
|
||||
|
||||
@Test fun handleResponseGivenResponseWhenMessageTooShortThenResultFalse() {
|
||||
|
|
Loading…
Reference in a new issue