Merge pull request #2736 from jbr7rr/medtrum-300U
Medtrum: Support for 300U and fixes
This commit is contained in:
commit
d5c7489ecb
19 changed files with 364 additions and 242 deletions
|
@ -410,10 +410,33 @@ enum class PumpType {
|
|||
baseBasalSpecialSteps = null,
|
||||
pumpCapability = PumpCapability.MedtrumCapabilities,
|
||||
isPatchPump = true,
|
||||
maxReservoirReading = 400,
|
||||
maxReservoirReading = 200,
|
||||
source = Source.Medtrum
|
||||
),
|
||||
MEDTRUM_UNTESTED(description = "Medtrum untested", model = "untested", parent = MEDTRUM_NANO);
|
||||
MEDTRUM_300U(
|
||||
description = "Medtrum 300U",
|
||||
manufacturer = ManufacturerType.Medtrum,
|
||||
model = "300U",
|
||||
bolusSize = 0.05,
|
||||
specialBolusSize = null,
|
||||
extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05, 30.0),
|
||||
pumpTempBasalType = PumpTempBasalType.Absolute,
|
||||
tbrSettings = DoseSettings(0.05, 30, 12 * 60, 0.0, 30.0),
|
||||
specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed,
|
||||
baseBasalMinValue = 0.05,
|
||||
baseBasalMaxValue = 30.0,
|
||||
baseBasalStep = 0.05,
|
||||
baseBasalSpecialSteps = null,
|
||||
pumpCapability = PumpCapability.MedtrumCapabilities,
|
||||
isPatchPump = true,
|
||||
maxReservoirReading = 300,
|
||||
source = Source.Medtrum
|
||||
),
|
||||
MEDTRUM_UNTESTED(
|
||||
description = "Medtrum untested",
|
||||
model = "untested",
|
||||
parent = MEDTRUM_NANO
|
||||
);
|
||||
|
||||
val description: String
|
||||
var manufacturer: ManufacturerType? = null
|
||||
|
@ -455,8 +478,10 @@ enum class PumpType {
|
|||
var hasCustomUnreachableAlertCheck = false
|
||||
private set
|
||||
var isPatchPump = false
|
||||
get() = parent?.isPatchPump ?: field
|
||||
private set
|
||||
var maxReservoirReading = 50
|
||||
get() = parent?.maxReservoirReading ?: field
|
||||
private set
|
||||
var supportBatteryLevel = true
|
||||
private set
|
||||
|
|
|
@ -60,6 +60,7 @@ fun PumpType.Companion.fromDbPumpType(pt: InterfaceIDs.PumpType): PumpType =
|
|||
InterfaceIDs.PumpType.DIACONN_G8 -> PumpType.DIACONN_G8
|
||||
InterfaceIDs.PumpType.EOPATCH2 -> PumpType.EOFLOW_EOPATCH2
|
||||
InterfaceIDs.PumpType.MEDTRUM -> PumpType.MEDTRUM_NANO
|
||||
InterfaceIDs.PumpType.MEDTRUM_300U -> PumpType.MEDTRUM_300U
|
||||
InterfaceIDs.PumpType.MEDTRUM_UNTESTED -> PumpType.MEDTRUM_UNTESTED
|
||||
InterfaceIDs.PumpType.CACHE -> PumpType.CACHE
|
||||
}
|
||||
|
@ -80,6 +81,7 @@ fun PumpType.Source.toDbSource(): UserEntry.Sources =
|
|||
PumpType.Source.OmnipodEros -> UserEntry.Sources.OmnipodEros
|
||||
PumpType.Source.OmnipodDash -> UserEntry.Sources.OmnipodDash
|
||||
PumpType.Source.EOPatch2 -> UserEntry.Sources.EOPatch2
|
||||
PumpType.Source.Medtrum -> UserEntry.Sources.Medtrum
|
||||
PumpType.Source.MDI -> UserEntry.Sources.MDI
|
||||
PumpType.Source.VirtualPump -> UserEntry.Sources.VirtualPump
|
||||
else -> UserEntry.Sources.Unknown
|
||||
|
@ -120,6 +122,7 @@ fun PumpType.toDbPumpType(): InterfaceIDs.PumpType =
|
|||
PumpType.DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
|
||||
PumpType.EOFLOW_EOPATCH2 -> InterfaceIDs.PumpType.EOPATCH2
|
||||
PumpType.MEDTRUM_NANO -> InterfaceIDs.PumpType.MEDTRUM
|
||||
PumpType.MEDTRUM_300U -> InterfaceIDs.PumpType.MEDTRUM_300U
|
||||
PumpType.MEDTRUM_UNTESTED -> InterfaceIDs.PumpType.MEDTRUM_UNTESTED
|
||||
PumpType.CACHE -> InterfaceIDs.PumpType.CACHE
|
||||
}
|
||||
|
|
|
@ -35,6 +35,14 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
|
|||
holder.isDividerAllowedBelow = false
|
||||
}
|
||||
|
||||
fun setMinNumber(min: Int) {
|
||||
this.validatorParameters.minNumber = min
|
||||
}
|
||||
|
||||
fun setMaxNumber(max: Int) {
|
||||
this.validatorParameters.maxNumber = max
|
||||
}
|
||||
|
||||
private fun obtainValidatorParameters(attrs: AttributeSet): DefaultEditTextValidator.Parameters {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FormEditText, 0, 0)
|
||||
return DefaultEditTextValidator.Parameters(
|
||||
|
|
|
@ -172,6 +172,7 @@ data class UserEntry(
|
|||
OmnipodEros,
|
||||
OmnipodDash, //No entry currently
|
||||
EOPatch2,
|
||||
Medtrum,
|
||||
MDI,
|
||||
VirtualPump,
|
||||
SMS, //From SMS plugin
|
||||
|
|
|
@ -44,6 +44,7 @@ data class InterfaceIDs(
|
|||
DIACONN_G8,
|
||||
EOPATCH2,
|
||||
MEDTRUM,
|
||||
MEDTRUM_300U,
|
||||
MEDTRUM_UNTESTED,
|
||||
USER,
|
||||
CACHE;
|
||||
|
|
|
@ -97,6 +97,7 @@ class UserEntryPresentationHelperImpl @Inject constructor(
|
|||
Sources.OmnipodEros -> R.drawable.ic_patch_pump_outline
|
||||
Sources.OmnipodDash -> R.drawable.ic_patch_pump_outline
|
||||
Sources.EOPatch2 -> info.nightscout.core.ui.R.drawable.ic_eopatch2_128
|
||||
Sources.Medtrum -> info.nightscout.core.ui.R.drawable.ic_medtrum_128
|
||||
Sources.MDI -> R.drawable.ic_ict
|
||||
Sources.VirtualPump -> R.drawable.ic_virtual_pump
|
||||
Sources.SMS -> R.drawable.ic_sms
|
||||
|
|
|
@ -15,6 +15,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
|
@ -127,33 +128,41 @@ import kotlin.math.abs
|
|||
|
||||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||
super.preprocessPreferences(preferenceFragment)
|
||||
|
||||
preprocessSerialSettings(preferenceFragment)
|
||||
preprocessAlarmSettings(preferenceFragment)
|
||||
preprocessMaxInsulinSettings(preferenceFragment)
|
||||
}
|
||||
|
||||
private fun preprocessSerialSettings(preferenceFragment: PreferenceFragmentCompat) {
|
||||
val serialSetting = preferenceFragment.findPreference<EditTextPreference>(rh.gs(R.string.key_sn_input))
|
||||
serialSetting?.isEnabled = !isInitialized()
|
||||
serialSetting?.setOnBindEditTextListener { editText ->
|
||||
editText.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(newValue: Editable?) {
|
||||
val newSN = newValue.toString().toLongOrNull(radix = 16)
|
||||
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN ?: 0)
|
||||
if (newDeviceType == MedtrumSnUtil.INVALID) {
|
||||
editText.error = rh.gs(R.string.sn_input_invalid)
|
||||
} else {
|
||||
editText.error = null
|
||||
serialSetting?.apply {
|
||||
isEnabled = !isInitialized()
|
||||
setOnBindEditTextListener { editText ->
|
||||
editText.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(newValue: Editable?) {
|
||||
val newSN = newValue?.toString()?.toLongOrNull(radix = 16) ?: 0
|
||||
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN)
|
||||
editText.error = if (newDeviceType == MedtrumSnUtil.INVALID) {
|
||||
rh.gs(R.string.sn_input_invalid)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
// Nothing to do here
|
||||
}
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
// Nothing to do here
|
||||
}
|
||||
})
|
||||
}
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val newSN = (newValue as? String)?.toLongOrNull(radix = 16) ?: 0
|
||||
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN)
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
// Nothing to do here
|
||||
}
|
||||
})
|
||||
}
|
||||
serialSetting?.setOnPreferenceChangeListener { _, newValue ->
|
||||
if (newValue is String) {
|
||||
val newSN = newValue.toLongOrNull(radix = 16)
|
||||
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN ?: 0)
|
||||
when {
|
||||
newDeviceType == MedtrumSnUtil.INVALID -> {
|
||||
preferenceFragment.activity?.let { activity ->
|
||||
|
@ -171,30 +180,61 @@ import kotlin.math.abs
|
|||
|
||||
else -> true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun preprocessAlarmSettings(preferenceFragment: PreferenceFragmentCompat) {
|
||||
val alarmSetting = preferenceFragment.findPreference<ListPreference>(rh.gs(R.string.key_alarm_setting))
|
||||
val allAlarmEntries = preferenceFragment.resources.getStringArray(R.array.alarmSettings)
|
||||
val allAlarmValues = preferenceFragment.resources.getStringArray(R.array.alarmSettingsValues)
|
||||
|
||||
if (allAlarmEntries.size < 8 || allAlarmValues.size < 8) {
|
||||
aapsLogger.error(LTag.PUMP, "Alarm settings array is not complete")
|
||||
return
|
||||
} else {
|
||||
when (medtrumPump.pumpType()) {
|
||||
PumpType.MEDTRUM_NANO, PumpType.MEDTRUM_300U -> {
|
||||
alarmSetting?.apply {
|
||||
entries = arrayOf(allAlarmEntries[6], allAlarmEntries[7]) // "Beep", "Silent"
|
||||
entryValues = arrayOf(allAlarmValues[6], allAlarmValues[7]) // "6", "7"
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
// Use default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun preprocessMaxInsulinSettings(preferenceFragment: PreferenceFragmentCompat) {
|
||||
val hourlyMaxSetting = preferenceFragment.findPreference<ValidatingEditTextPreference>(rh.gs(R.string.key_hourly_max_insulin))
|
||||
val dailyMaxSetting = preferenceFragment.findPreference<ValidatingEditTextPreference>(rh.gs(R.string.key_daily_max_insulin))
|
||||
|
||||
val hourlyMaxValue = hourlyMaxSetting?.text?.toIntOrNull() ?: 0
|
||||
val newDailyMaxMinValue = if (hourlyMaxValue > 20) hourlyMaxValue else 20
|
||||
dailyMaxSetting?.setMinNumber(newDailyMaxMinValue)
|
||||
|
||||
val pumpTypeSettings = when (medtrumPump.pumpType()) {
|
||||
PumpType.MEDTRUM_NANO -> Pair(40, 180) // maxHourlyMax, maxDailyMax
|
||||
PumpType.MEDTRUM_300U -> Pair(60, 270)
|
||||
else -> Pair(40, 180)
|
||||
}
|
||||
|
||||
when (medtrumPump.pumpType()) {
|
||||
PumpType.MEDTRUM_NANO -> {
|
||||
alarmSetting?.entries = arrayOf(allAlarmEntries[6], allAlarmEntries[7]) // "Beep", "Silent"
|
||||
alarmSetting?.entryValues = arrayOf(allAlarmValues[6], allAlarmValues[7]) // "6", "7"
|
||||
hourlyMaxSetting?.apply {
|
||||
setMaxNumber(pumpTypeSettings.first)
|
||||
val hourlyCurrentValue = text?.toIntOrNull() ?: 0
|
||||
if (hourlyCurrentValue > pumpTypeSettings.first) {
|
||||
text = pumpTypeSettings.first.toString()
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
// Use Nano settings for unknown pumps
|
||||
alarmSetting?.entries = arrayOf(allAlarmEntries[6], allAlarmEntries[7]) // "Beep", "Silent"
|
||||
alarmSetting?.entryValues = arrayOf(allAlarmValues[6], allAlarmValues[7]) // "6", "7"
|
||||
dailyMaxSetting?.apply {
|
||||
setMaxNumber(pumpTypeSettings.second)
|
||||
val dailyCurrentValue = text?.toIntOrNull() ?: 0
|
||||
when {
|
||||
dailyCurrentValue < newDailyMaxMinValue -> text = newDailyMaxMinValue.toString()
|
||||
dailyCurrentValue > pumpTypeSettings.second -> text = pumpTypeSettings.second.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,6 +260,7 @@ import kotlin.math.abs
|
|||
override fun isHandshakeInProgress(): Boolean = false
|
||||
|
||||
override fun finishHandshaking() {
|
||||
// Unused
|
||||
}
|
||||
|
||||
override fun connect(reason: String) {
|
||||
|
@ -417,6 +458,7 @@ import kotlin.math.abs
|
|||
try {
|
||||
extended.put("ActiveProfile", profileName)
|
||||
} catch (ignored: Exception) {
|
||||
// Ignore
|
||||
}
|
||||
pumpJson.put("status", status)
|
||||
pumpJson.put("extended", extended)
|
||||
|
@ -472,6 +514,7 @@ import kotlin.math.abs
|
|||
}
|
||||
|
||||
override fun executeCustomAction(customActionType: CustomActionType) {
|
||||
// Unused
|
||||
}
|
||||
|
||||
override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? {
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.pump.medtrum
|
|||
|
||||
import android.util.Base64
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.interfaces.pump.defs.PumpType
|
||||
|
@ -294,6 +295,7 @@ class MedtrumPump @Inject constructor(
|
|||
fun pumpType(type: Int): PumpType =
|
||||
when (type) {
|
||||
MedtrumSnUtil.MD_0201, MedtrumSnUtil.MD_8201 -> PumpType.MEDTRUM_NANO
|
||||
MedtrumSnUtil.MD_8301 -> PumpType.MEDTRUM_300U
|
||||
else -> PumpType.MEDTRUM_UNTESTED
|
||||
}
|
||||
|
||||
|
@ -333,7 +335,7 @@ class MedtrumPump @Inject constructor(
|
|||
|
||||
val date = GregorianCalendar()
|
||||
date.timeInMillis = timestamp
|
||||
val hourOfDayMinutes = date.get(GregorianCalendar.HOUR_OF_DAY) * 60 + date.get(GregorianCalendar.MINUTE)
|
||||
val hourOfDayMinutes = date[GregorianCalendar.HOUR_OF_DAY] * 60 + date[GregorianCalendar.MINUTE]
|
||||
|
||||
for (index in 0 until basalCount) {
|
||||
val currentIndex = 1 + (index * 3)
|
||||
|
@ -354,7 +356,6 @@ class MedtrumPump @Inject constructor(
|
|||
aapsLogger.debug(LTag.PUMP, "getHourlyBasalFromMedtrumProfileArray: basal: $basal")
|
||||
break
|
||||
}
|
||||
// aapsLogger.debug(LTag.PUMP, "getHourlyBasalFromMedtrumProfileArray: rate: $rate, startMinutes: $startMinutes, endMinutes: $endMinutes")
|
||||
}
|
||||
return basal
|
||||
}
|
||||
|
@ -378,59 +379,67 @@ class MedtrumPump @Inject constructor(
|
|||
)
|
||||
@Suppress("UNNECESSARY_SAFE_CALL") // Safe call to allow mocks to return null
|
||||
val expectedTemporaryBasal = pumpSync.expectedPumpState()?.temporaryBasal
|
||||
if (basalType.isTempBasal() && expectedTemporaryBasal?.pumpId != basalStartTime) {
|
||||
// Note: temporaryBasalInfo will be removed from temporaryBasalStorage after this call
|
||||
val temporaryBasalInfo = temporaryBasalStorage.findTemporaryBasal(basalStartTime, basalRate)
|
||||
when {
|
||||
basalType.isTempBasal() && expectedTemporaryBasal?.pumpId != basalStartTime -> {
|
||||
// Note: temporaryBasalInfo will be removed from temporaryBasalStorage after this call
|
||||
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(FAKE_TBR_LENGTH).msecs()
|
||||
val adjustedBasalRate = if (basalType == BasalType.ABSOLUTE_TEMP) {
|
||||
basalRate
|
||||
} else {
|
||||
(basalRate / baseBasalRate) * 100 // calculate the percentage of the original basal rate
|
||||
}
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = adjustedBasalRate,
|
||||
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} temporaryBasalInfo: $temporaryBasalInfo, expectedTemporaryBasal: $expectedTemporaryBasal"
|
||||
)
|
||||
} else if (basalType.isSuspendedByPump() && expectedTemporaryBasal?.pumpId != basalStartTime) {
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = 0.0,
|
||||
duration = T.mins(FAKE_TBR_LENGTH).msecs(),
|
||||
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_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) expectedTemporaryBasal: $expectedTemporaryBasal"
|
||||
)
|
||||
} else if (basalType == BasalType.NONE && expectedTemporaryBasal?.rate != basalRate && expectedTemporaryBasal?.duration != T.mins(FAKE_TBR_LENGTH).msecs()) {
|
||||
// Pump suspended, set fake TBR
|
||||
setFakeTBR()
|
||||
} else if (basalType == BasalType.STANDARD) {
|
||||
if (expectedTemporaryBasal != null) {
|
||||
// Pump resumed, sync end
|
||||
val success = pumpSync.syncStopTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime + 250, // Time of normal basal start = time of tbr end
|
||||
endPumpId = basalStartTime + 250, // +250ms Make sure there is time between start and stop of TBR
|
||||
// If duration is unknown, no way to get it now, set patch lifetime as duration
|
||||
val duration = temporaryBasalInfo?.duration ?: T.mins(FAKE_TBR_LENGTH).msecs()
|
||||
val adjustedBasalRate = if (basalType == BasalType.ABSOLUTE_TEMP) {
|
||||
basalRate
|
||||
} else {
|
||||
(basalRate / baseBasalRate) * 100 // calculate the percentage of the original basal rate
|
||||
}
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = adjustedBasalRate,
|
||||
duration = duration,
|
||||
isAbsolute = (basalType == BasalType.ABSOLUTE_TEMP),
|
||||
type = temporaryBasalInfo?.type,
|
||||
pumpId = basalStartTime,
|
||||
pumpType = pumpType(),
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "handleBasalStatusUpdate: EVENT TEMP_END ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) success: $success")
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"handleBasalStatusUpdate: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + "Rate: $basalRate Duration: ${duration} temporaryBasalInfo: $temporaryBasalInfo, expectedTemporaryBasal: $expectedTemporaryBasal"
|
||||
)
|
||||
}
|
||||
|
||||
basalType.isSuspendedByPump() && expectedTemporaryBasal?.pumpId != basalStartTime -> {
|
||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime,
|
||||
rate = 0.0,
|
||||
duration = T.mins(FAKE_TBR_LENGTH).msecs(),
|
||||
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_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) expectedTemporaryBasal: $expectedTemporaryBasal"
|
||||
)
|
||||
}
|
||||
|
||||
basalType == BasalType.NONE && expectedTemporaryBasal?.rate != basalRate && expectedTemporaryBasal?.duration != T.mins(FAKE_TBR_LENGTH).msecs() -> {
|
||||
// Pump suspended, set fake TBR
|
||||
setFakeTBR()
|
||||
}
|
||||
|
||||
basalType == BasalType.STANDARD -> {
|
||||
if (expectedTemporaryBasal != null) {
|
||||
// Pump resumed, sync end
|
||||
val success = pumpSync.syncStopTemporaryBasalWithPumpId(
|
||||
timestamp = basalStartTime + 250, // Time of normal basal start = time of tbr end
|
||||
endPumpId = basalStartTime + 250, // +250ms Make sure there is time between start and stop of TBR
|
||||
pumpType = pumpType(),
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "handleBasalStatusUpdate: EVENT TEMP_END ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) success: $success")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,6 +538,26 @@ class MedtrumPump @Inject constructor(
|
|||
return rh.gs(stringId)
|
||||
}
|
||||
|
||||
fun handleNewPatch(newPatchId: Long, sequenceNumber: Int, newStartTime: Long) {
|
||||
patchId = newPatchId
|
||||
patchStartTime = newStartTime
|
||||
currentSequenceNumber = sequenceNumber // We are activated, set the new seq nr
|
||||
syncedSequenceNumber = 1 // Always start with 1
|
||||
// Sync cannula change
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = newStartTime,
|
||||
type = DetailedBolusInfo.EventType.CANNULA_CHANGE,
|
||||
pumpType = pumpType(),
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = newStartTime,
|
||||
type = DetailedBolusInfo.EventType.INSULIN_CHANGE,
|
||||
pumpType = pumpType(),
|
||||
pumpSerial = pumpSN.toString(radix = 16)
|
||||
)
|
||||
}
|
||||
|
||||
private fun saveActiveAlarms() {
|
||||
val alarmsStr = activeAlarms.joinToString(separator = ",") { it.name }
|
||||
sp.putString(R.string.key_active_alarms, alarmsStr)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.pump.medtrum.comm.packets
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
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
|
||||
|
@ -93,24 +92,8 @@ class ActivatePacket(injector: HasAndroidInjector, private val basalProfile: Byt
|
|||
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 ()
|
||||
|
||||
// Sync cannula change
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
type = DetailedBolusInfo.EventType.CANNULA_CHANGE,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
type = DetailedBolusInfo.EventType.INSULIN_CHANGE,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
medtrumPump.handleNewPatch(patchId, basalSequence, System.currentTimeMillis())
|
||||
|
||||
// Update the actual basal profile
|
||||
medtrumPump.actualBasalProfile = basalProfile
|
||||
|
|
|
@ -111,91 +111,99 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
|
|||
"$bolusExtendedDuration, " + "bolusExtendedDelivered: $bolusExtendedDelivered, bolusCarb: $bolusCarb, bolusGlucose: $bolusGlucose, bolusIOB: $bolusIOB, unknown1: $unknown1, unknown2: $unknown2, " + "bolusType: $bolusType, bolusWizard: $bolusWizard"
|
||||
)
|
||||
|
||||
if (bolusType == BolusType.NORMAL) {
|
||||
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||
var newRecord = false
|
||||
if (detailedBolusInfo != null) {
|
||||
val syncOk = pumpSync.syncBolusWithTempId(
|
||||
when (bolusType) {
|
||||
BolusType.NORMAL -> {
|
||||
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||
var newRecord = false
|
||||
if (detailedBolusInfo != null) {
|
||||
val syncOk = pumpSync.syncBolusWithTempId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
temporaryId = detailedBolusInfo.timestamp,
|
||||
type = detailedBolusInfo.bolusType,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
if (!syncOk) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Failed to sync bolus with tempId: ${detailedBolusInfo.timestamp}")
|
||||
// detailedInfo can be from another similar record. Reinsert
|
||||
detailedBolusInfoStorage.add(detailedBolusInfo)
|
||||
}
|
||||
} else {
|
||||
newRecord = pumpSync.syncBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
type = null,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
}
|
||||
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
||||
)
|
||||
if (bolusStartTime > medtrumPump.lastBolusTime) {
|
||||
medtrumPump.lastBolusTime = bolusStartTime
|
||||
medtrumPump.lastBolusAmount = bolusNormalDelivered
|
||||
}
|
||||
}
|
||||
|
||||
BolusType.EXTENDED -> {
|
||||
val newRecord = pumpSync.syncExtendedBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
temporaryId = detailedBolusInfo.timestamp,
|
||||
type = detailedBolusInfo.bolusType,
|
||||
amount = bolusExtendedDelivered,
|
||||
duration = bolusExtendedDuration,
|
||||
isEmulatingTB = false,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
if (!syncOk) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Failed to sync bolus with tempId: ${detailedBolusInfo.timestamp}")
|
||||
// detailedInfo can be from another similar record. Reinsert
|
||||
detailedBolusInfoStorage.add(detailedBolusInfo)
|
||||
}
|
||||
} else {
|
||||
newRecord = pumpSync.syncBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
type = null,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT EXTENDED BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
||||
)
|
||||
}
|
||||
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
||||
)
|
||||
if (bolusStartTime > medtrumPump.lastBolusTime) {
|
||||
medtrumPump.lastBolusTime = bolusStartTime
|
||||
medtrumPump.lastBolusAmount = bolusNormalDelivered
|
||||
BolusType.COMBI -> {
|
||||
// Note, this should never happen, as we don't use combo bolus
|
||||
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||
val newRecord = pumpSync.syncBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
type = detailedBolusInfo?.bolusType,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
pumpSync.syncExtendedBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusExtendedDelivered,
|
||||
duration = bolusExtendedDuration,
|
||||
isEmulatingTB = false,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.error(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT COMBI BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U Extended: ${bolusExtendedDelivered} THIS SHOULD NOT HAPPEN!!!"
|
||||
)
|
||||
if (!newRecord && detailedBolusInfo != null) {
|
||||
// detailedInfo can be from another similar record. Reinsert
|
||||
detailedBolusInfoStorage.add(detailedBolusInfo)
|
||||
}
|
||||
if (bolusStartTime > medtrumPump.lastBolusTime) {
|
||||
medtrumPump.lastBolusTime = bolusStartTime
|
||||
medtrumPump.lastBolusAmount = bolusNormalDelivered
|
||||
}
|
||||
}
|
||||
} else if (bolusType == BolusType.EXTENDED) {
|
||||
val newRecord = pumpSync.syncExtendedBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusExtendedDelivered,
|
||||
duration = bolusExtendedDuration,
|
||||
isEmulatingTB = false,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.debug(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT EXTENDED BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
||||
)
|
||||
} else if (bolusType == BolusType.COMBI) {
|
||||
// Note, this should never happen, as we don't use combo bolus
|
||||
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||
val newRecord = pumpSync.syncBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusNormalDelivered,
|
||||
type = detailedBolusInfo?.bolusType,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
pumpSync.syncExtendedBolusWithPumpId(
|
||||
timestamp = bolusStartTime,
|
||||
amount = bolusExtendedDelivered,
|
||||
duration = bolusExtendedDuration,
|
||||
isEmulatingTB = false,
|
||||
pumpId = bolusStartTime,
|
||||
pumpType = medtrumPump.pumpType(),
|
||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||
)
|
||||
aapsLogger.error(
|
||||
LTag.PUMPCOMM,
|
||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT COMBI BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U Extended: ${bolusExtendedDelivered} THIS SHOULD NOT HAPPEN!!!"
|
||||
)
|
||||
if (!newRecord && detailedBolusInfo != null) {
|
||||
// detailedInfo can be from another similar record. Reinsert
|
||||
detailedBolusInfoStorage.add(detailedBolusInfo)
|
||||
|
||||
else -> {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Unknown bolus type: $bolusType")
|
||||
}
|
||||
if (bolusStartTime > medtrumPump.lastBolusTime) {
|
||||
medtrumPump.lastBolusTime = bolusStartTime
|
||||
medtrumPump.lastBolusAmount = bolusNormalDelivered
|
||||
}
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Unknown bolus type: $bolusType")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
fun handleMaskedMessage(data: ByteArray) {
|
||||
val fieldMask = data.copyOfRange(0, 2).toInt()
|
||||
var offset = 2
|
||||
var newPatchStartTime: Long? = null
|
||||
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Message field mask: $fieldMask")
|
||||
|
||||
|
@ -148,12 +149,12 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
|
||||
if (fieldMask and MASK_START_TIME != 0) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Start time notification received")
|
||||
val patchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset, offset + 4).toLong())
|
||||
if (medtrumPump.patchStartTime != patchStartTime) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time changed from ${medtrumPump.patchStartTime} to $patchStartTime")
|
||||
medtrumPump.patchStartTime = patchStartTime
|
||||
newPatchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset, offset + 4).toLong())
|
||||
if (medtrumPump.patchStartTime != newPatchStartTime) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time changed from ${medtrumPump.patchStartTime} to $newPatchStartTime")
|
||||
medtrumPump.patchStartTime = newPatchStartTime
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time: ${patchStartTime}")
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time: $newPatchStartTime")
|
||||
offset += 4
|
||||
}
|
||||
|
||||
|
@ -176,6 +177,11 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
|||
val patchId = data.copyOfRange(offset + 2, offset + 4).toLong()
|
||||
if (patchId != medtrumPump.patchId) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "handleMaskedMessage: We got wrong patch id!")
|
||||
if (newPatchStartTime != null) {
|
||||
// This is a fallback for when the activate packet did not receive the ack but the patch activated anyway
|
||||
aapsLogger.error(LTag.PUMPCOMM, "handleMaskedMessage: Also Received start time in this packet, registering new patch id: $patchId")
|
||||
medtrumPump.handleNewPatch(patchId, sequence, newPatchStartTime)
|
||||
}
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Last known sequence number: ${medtrumPump.currentSequenceNumber}, patch id: ${patchId}")
|
||||
offset += 4
|
||||
|
|
|
@ -39,11 +39,11 @@ class Crypt {
|
|||
}
|
||||
|
||||
private fun randomGen(input: Long): Long {
|
||||
val A = 16807
|
||||
val Q = 127773
|
||||
val R = 2836
|
||||
val tmp1 = input / Q
|
||||
var ret = (input - (tmp1 * Q)) * A - (tmp1 * R)
|
||||
val a = 16807
|
||||
val q = 127773
|
||||
val r = 2836
|
||||
val tmp1 = input / q
|
||||
var ret = (input - (tmp1 * q)) * a - (tmp1 * r)
|
||||
if (ret < 0) {
|
||||
ret += 2147483647L
|
||||
}
|
||||
|
|
|
@ -310,9 +310,7 @@ class BLEComm @Inject internal constructor(
|
|||
private fun readDescriptor(descriptor: BluetoothGattDescriptor?) {
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "readDescriptor")
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null || descriptor == null) {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
handleNotInitialized()
|
||||
return
|
||||
}
|
||||
mBluetoothGatt?.readDescriptor(descriptor)
|
||||
|
@ -323,9 +321,7 @@ class BLEComm @Inject internal constructor(
|
|||
aapsLogger.debug(LTag.PUMPBTCOMM, "checkDescriptor")
|
||||
val service = getGattService()
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null || service == null) {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
handleNotInitialized()
|
||||
return
|
||||
}
|
||||
if (descriptor.value.toInt() > 0) {
|
||||
|
@ -352,9 +348,7 @@ class BLEComm @Inject internal constructor(
|
|||
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
handleNotInitialized()
|
||||
return
|
||||
}
|
||||
mBluetoothGatt?.setCharacteristicNotification(characteristic, enabled)
|
||||
|
@ -366,7 +360,7 @@ class BLEComm @Inject internal constructor(
|
|||
it.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
|
||||
mBluetoothGatt?.writeDescriptor(it)
|
||||
} else {
|
||||
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -417,9 +411,7 @@ class BLEComm @Inject internal constructor(
|
|||
private fun getGattService(): BluetoothGattService? {
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "getGattService")
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
handleNotInitialized()
|
||||
return null
|
||||
}
|
||||
return mBluetoothGatt?.getService(UUID.fromString(SERVICE_UUID))
|
||||
|
@ -431,9 +423,7 @@ class BLEComm @Inject internal constructor(
|
|||
private fun writeCharacteristic(characteristic: BluetoothGattCharacteristic, data: ByteArray?) {
|
||||
handler.postDelayed({
|
||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
handleNotInitialized()
|
||||
} else {
|
||||
characteristic.value = data
|
||||
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
|
||||
|
@ -456,7 +446,7 @@ class BLEComm @Inject internal constructor(
|
|||
var uuid: String
|
||||
val gattCharacteristics = gattService.characteristics
|
||||
for (i in 0 until gattCharacteristics.size) {
|
||||
val gattCharacteristic = gattCharacteristics.get(i)
|
||||
val gattCharacteristic = gattCharacteristics[i]
|
||||
// Check whether read or write properties is set, the pump needs us to enable notifications on all characteristics that have these properties
|
||||
if (gattCharacteristic.properties and NEEDS_ENABLE > 0) {
|
||||
handler.postDelayed({
|
||||
|
@ -472,4 +462,11 @@ class BLEComm @Inject internal constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNotInitialized() {
|
||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||
isConnecting = false
|
||||
isConnected = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,20 +135,13 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
}
|
||||
}, fabricPrivacy::logException)
|
||||
scope.launch {
|
||||
medtrumPump.pumpStateFlow.collect { state ->
|
||||
handlePumpStateUpdate(state)
|
||||
medtrumPump.pumpStateFlow.collect { pumpState ->
|
||||
handlePumpStateUpdate(pumpState)
|
||||
}
|
||||
}
|
||||
scope.launch {
|
||||
medtrumPump.connectionStateFlow.collect { state ->
|
||||
if (medtrumPlugin.isInitialized()) {
|
||||
when (state) {
|
||||
ConnectionState.CONNECTED -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
||||
ConnectionState.DISCONNECTED -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED))
|
||||
ConnectionState.CONNECTING -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTING))
|
||||
ConnectionState.DISCONNECTING -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTING))
|
||||
}
|
||||
}
|
||||
medtrumPump.connectionStateFlow.collect { connectionState ->
|
||||
handleConnectionStateChange(connectionState)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,23 +156,29 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
|
||||
fun connect(from: String): Boolean {
|
||||
aapsLogger.debug(LTag.PUMP, "connect: called from: $from")
|
||||
if (currentState is IdleState) {
|
||||
medtrumPump.connectionState = ConnectionState.CONNECTING
|
||||
return bleComm.connect(from, medtrumPump.pumpSN)
|
||||
} else if (currentState is ReadyState) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in ReadyState from: $from")
|
||||
if (isConnected) {
|
||||
aapsLogger.debug(LTag.PUMP, "connect: already connected")
|
||||
return true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.PUMP, "connect: not connected, resetting state and trying to connect")
|
||||
toState(IdleState())
|
||||
when (currentState) {
|
||||
is IdleState -> {
|
||||
medtrumPump.connectionState = ConnectionState.CONNECTING
|
||||
return bleComm.connect(from, medtrumPump.pumpSN)
|
||||
}
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in state: $currentState from: $from")
|
||||
return false
|
||||
|
||||
is ReadyState -> {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in ReadyState from: $from")
|
||||
return if (isConnected) {
|
||||
aapsLogger.debug(LTag.PUMP, "connect: already connected")
|
||||
true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.PUMP, "connect: not connected, resetting state and trying to connect")
|
||||
toState(IdleState())
|
||||
medtrumPump.connectionState = ConnectionState.CONNECTING
|
||||
bleComm.connect(from, medtrumPump.pumpSN)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in state: $currentState from: $from")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,8 +246,8 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
timeUpdateNotification(result)
|
||||
}
|
||||
// Do this here, because TBR can be cancelled due to time change by connect flow
|
||||
if (needLoadHistory) {
|
||||
if (result) result = loadEvents()
|
||||
if (needLoadHistory && result) {
|
||||
result = loadEvents()
|
||||
}
|
||||
if (result) medtrumPump.needCheckTimeUpdate = false
|
||||
return result
|
||||
|
@ -606,6 +605,17 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleConnectionStateChange(connectionState: ConnectionState) {
|
||||
if (medtrumPlugin.isInitialized()) {
|
||||
when (connectionState) {
|
||||
ConnectionState.CONNECTED -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
||||
ConnectionState.DISCONNECTED -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED))
|
||||
ConnectionState.CONNECTING -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTING))
|
||||
ConnectionState.DISCONNECTING -> rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTING))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** BLECommCallbacks */
|
||||
override fun onBLEConnected() {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onBLEConnected")
|
||||
|
@ -676,7 +686,10 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
|||
protected var responseSuccess = false
|
||||
protected var sendRetryCounter = 0
|
||||
|
||||
open fun onEnter() {}
|
||||
open fun onEnter() {
|
||||
// Used when a state is entered
|
||||
}
|
||||
|
||||
open fun onIndication(data: ByteArray) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "onIndication: " + this.toString() + "Should not be called here!")
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import info.nightscout.pump.medtrum.ui.event.SingleLiveEvent
|
|||
import info.nightscout.pump.medtrum.ui.event.UIEvent
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.queue.CommandQueue
|
||||
import info.nightscout.pump.medtrum.MedtrumPlugin
|
||||
import info.nightscout.pump.medtrum.MedtrumPump
|
||||
import info.nightscout.pump.medtrum.R
|
||||
import info.nightscout.pump.medtrum.code.ConnectionState
|
||||
|
@ -28,6 +29,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
|||
private val profileFunction: ProfileFunction,
|
||||
private val commandQueue: CommandQueue,
|
||||
private val dateUtil: DateUtil,
|
||||
private val medtrumPlugin: MedtrumPlugin,
|
||||
val medtrumPump: MedtrumPump
|
||||
) : BaseViewModel<MedtrumBaseNavigator>() {
|
||||
|
||||
|
@ -128,7 +130,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
|||
scope.launch {
|
||||
medtrumPump.bolusAmountDeliveredFlow.collect { bolusAmount ->
|
||||
aapsLogger.debug(LTag.PUMP, "MedtrumViewModel bolusAmountDeliveredFlow: $bolusAmount")
|
||||
if (!medtrumPump.bolusDone) {
|
||||
if (!medtrumPump.bolusDone && medtrumPlugin.isInitialized()) {
|
||||
_activeBolusStatus.postValue(
|
||||
dateUtil.timeString(medtrumPump.bolusStartTime) + " " + dateUtil.sinceString(medtrumPump.bolusStartTime, rh)
|
||||
+ " " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, bolusAmount) + " / " + rh.gs(
|
||||
|
@ -145,6 +147,8 @@ class MedtrumOverviewViewModel @Inject constructor(
|
|||
kotlinx.coroutines.delay(T.mins(1).msecs())
|
||||
}
|
||||
}
|
||||
// Update gui on init
|
||||
updateGUI()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
@ -189,7 +193,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
|||
)
|
||||
else _lastBolus.postValue("")
|
||||
}
|
||||
if (medtrumPump.bolusDone) {
|
||||
if (medtrumPump.bolusDone || !medtrumPlugin.isInitialized()) {
|
||||
_activeBolusStatus.postValue("")
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ class MedtrumViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
ConnectionState.CONNECTING, ConnectionState.DISCONNECTING -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
|||
|
||||
@Singleton
|
||||
class ViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
var creator: Provider<out ViewModel>? = creators[modelClass]
|
||||
if (creator == null) {
|
||||
|
@ -26,9 +27,7 @@ class ViewModelFactory @Inject constructor(private val creators: Map<Class<out V
|
|||
}
|
||||
}
|
||||
}
|
||||
if (creator == null) {
|
||||
throw IllegalArgumentException("unknown model class $modelClass")
|
||||
}
|
||||
requireNotNull(creator) { "unknown model class $modelClass" }
|
||||
try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return creator.get() as T
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<string name="medtrum">Medtrum</string>
|
||||
<string name="medtrum_pump_shortname">MT</string>
|
||||
<string name="medtrum_pump_description">Pump integration for Medtrum Nano</string>
|
||||
<string name="medtrum_pump_description">Pump integration for Medtrum Nano and Medtrum 300U</string>
|
||||
<string name="medtrum_pump_setting">Medtrum pump settings</string>
|
||||
<string name="pump_error">Pump error: %1$s !! </string>
|
||||
<string name="pump_is_suspended">Pump is suspended</string>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
android:title="@string/daily_max_insulin_title"
|
||||
android:dialogMessage="@string/daily_max_insulin_summary"
|
||||
validate:maxNumber="180"
|
||||
validate:minNumber="25"
|
||||
validate:minNumber="20"
|
||||
validate:testType="numericRange" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
|
Loading…
Reference in a new issue