diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/pump/defs/PumpType.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/pump/defs/PumpType.kt index 3bd481629c..b6d7400e3e 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/pump/defs/PumpType.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/pump/defs/PumpType.kt @@ -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 diff --git a/core/main/src/main/java/info/nightscout/core/pump/PumpTypeExtension.kt b/core/main/src/main/java/info/nightscout/core/pump/PumpTypeExtension.kt index 321365cba4..f92f0ccecf 100644 --- a/core/main/src/main/java/info/nightscout/core/pump/PumpTypeExtension.kt +++ b/core/main/src/main/java/info/nightscout/core/pump/PumpTypeExtension.kt @@ -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 } diff --git a/core/validators/src/main/java/info/nightscout/core/validators/ValidatingEditTextPreference.kt b/core/validators/src/main/java/info/nightscout/core/validators/ValidatingEditTextPreference.kt index 7c37716c68..eb4431f79e 100644 --- a/core/validators/src/main/java/info/nightscout/core/validators/ValidatingEditTextPreference.kt +++ b/core/validators/src/main/java/info/nightscout/core/validators/ValidatingEditTextPreference.kt @@ -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( diff --git a/database/entities/src/main/java/info/nightscout/database/entities/UserEntry.kt b/database/entities/src/main/java/info/nightscout/database/entities/UserEntry.kt index c91244ead4..a39ea837b6 100644 --- a/database/entities/src/main/java/info/nightscout/database/entities/UserEntry.kt +++ b/database/entities/src/main/java/info/nightscout/database/entities/UserEntry.kt @@ -172,6 +172,7 @@ data class UserEntry( OmnipodEros, OmnipodDash, //No entry currently EOPatch2, + Medtrum, MDI, VirtualPump, SMS, //From SMS plugin diff --git a/database/entities/src/main/java/info/nightscout/database/entities/embedments/InterfaceIDs.kt b/database/entities/src/main/java/info/nightscout/database/entities/embedments/InterfaceIDs.kt index 0a244aa3c6..a711ef22e5 100644 --- a/database/entities/src/main/java/info/nightscout/database/entities/embedments/InterfaceIDs.kt +++ b/database/entities/src/main/java/info/nightscout/database/entities/embedments/InterfaceIDs.kt @@ -44,6 +44,7 @@ data class InterfaceIDs( DIACONN_G8, EOPATCH2, MEDTRUM, + MEDTRUM_300U, MEDTRUM_UNTESTED, USER, CACHE; diff --git a/implementation/src/main/java/info/nightscout/implementation/userEntry/UserEntryPresentationHelperImpl.kt b/implementation/src/main/java/info/nightscout/implementation/userEntry/UserEntryPresentationHelperImpl.kt index e3b0417edd..825394718f 100644 --- a/implementation/src/main/java/info/nightscout/implementation/userEntry/UserEntryPresentationHelperImpl.kt +++ b/implementation/src/main/java/info/nightscout/implementation/userEntry/UserEntryPresentationHelperImpl.kt @@ -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 diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt index 2aa61cda52..d6e97dbe88 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt @@ -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(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(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(rh.gs(R.string.key_hourly_max_insulin)) + val dailyMaxSetting = preferenceFragment.findPreference(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? { diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPump.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPump.kt index 094e5ebaf7..b057c98a96 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPump.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPump.kt @@ -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) diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/ActivatePacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/ActivatePacket.kt index 8ec37c2e2c..44264e52ae 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/ActivatePacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/ActivatePacket.kt @@ -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 diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt index 3c3757f66e..669e512ee9 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt @@ -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") } } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt index e9a1cdae87..0657319396 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt @@ -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 diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/encryption/Crypt.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/encryption/Crypt.kt index a4f7e6c0df..cf958b224a 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/encryption/Crypt.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/encryption/Crypt.kt @@ -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 } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt index 13de8dfacc..ff7a82a227 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt @@ -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 + } } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt index b9efa8f5a2..aa31cd1459 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt @@ -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!") } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt index 6ab279d1be..a3c6e15620 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt @@ -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() { @@ -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("") } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt index f12f49e6aa..3ba5be8011 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt @@ -80,6 +80,7 @@ class MedtrumViewModel @Inject constructor( } ConnectionState.CONNECTING, ConnectionState.DISCONNECTING -> { + // Do nothing } } } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/ViewModelFactory.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/ViewModelFactory.kt index 0baf6a7679..b0e8b13259 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/ViewModelFactory.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/ViewModelFactory.kt @@ -16,6 +16,7 @@ internal annotation class ViewModelKey(val value: KClass) @Singleton class ViewModelFactory @Inject constructor(private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { var creator: Provider? = creators[modelClass] if (creator == null) { @@ -26,9 +27,7 @@ class ViewModelFactory @Inject constructor(private val creators: MapMedtrum MT - Pump integration for Medtrum Nano + Pump integration for Medtrum Nano and Medtrum 300U Medtrum pump settings Pump error: %1$s !! Pump is suspended diff --git a/pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml b/pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml index 64081101e5..505e1cd747 100644 --- a/pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml +++ b/pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml @@ -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" />