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,
|
baseBasalSpecialSteps = null,
|
||||||
pumpCapability = PumpCapability.MedtrumCapabilities,
|
pumpCapability = PumpCapability.MedtrumCapabilities,
|
||||||
isPatchPump = true,
|
isPatchPump = true,
|
||||||
maxReservoirReading = 400,
|
maxReservoirReading = 200,
|
||||||
source = Source.Medtrum
|
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
|
val description: String
|
||||||
var manufacturer: ManufacturerType? = null
|
var manufacturer: ManufacturerType? = null
|
||||||
|
@ -455,8 +478,10 @@ enum class PumpType {
|
||||||
var hasCustomUnreachableAlertCheck = false
|
var hasCustomUnreachableAlertCheck = false
|
||||||
private set
|
private set
|
||||||
var isPatchPump = false
|
var isPatchPump = false
|
||||||
|
get() = parent?.isPatchPump ?: field
|
||||||
private set
|
private set
|
||||||
var maxReservoirReading = 50
|
var maxReservoirReading = 50
|
||||||
|
get() = parent?.maxReservoirReading ?: field
|
||||||
private set
|
private set
|
||||||
var supportBatteryLevel = true
|
var supportBatteryLevel = true
|
||||||
private set
|
private set
|
||||||
|
|
|
@ -60,6 +60,7 @@ fun PumpType.Companion.fromDbPumpType(pt: InterfaceIDs.PumpType): PumpType =
|
||||||
InterfaceIDs.PumpType.DIACONN_G8 -> PumpType.DIACONN_G8
|
InterfaceIDs.PumpType.DIACONN_G8 -> PumpType.DIACONN_G8
|
||||||
InterfaceIDs.PumpType.EOPATCH2 -> PumpType.EOFLOW_EOPATCH2
|
InterfaceIDs.PumpType.EOPATCH2 -> PumpType.EOFLOW_EOPATCH2
|
||||||
InterfaceIDs.PumpType.MEDTRUM -> PumpType.MEDTRUM_NANO
|
InterfaceIDs.PumpType.MEDTRUM -> PumpType.MEDTRUM_NANO
|
||||||
|
InterfaceIDs.PumpType.MEDTRUM_300U -> PumpType.MEDTRUM_300U
|
||||||
InterfaceIDs.PumpType.MEDTRUM_UNTESTED -> PumpType.MEDTRUM_UNTESTED
|
InterfaceIDs.PumpType.MEDTRUM_UNTESTED -> PumpType.MEDTRUM_UNTESTED
|
||||||
InterfaceIDs.PumpType.CACHE -> PumpType.CACHE
|
InterfaceIDs.PumpType.CACHE -> PumpType.CACHE
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ fun PumpType.Source.toDbSource(): UserEntry.Sources =
|
||||||
PumpType.Source.OmnipodEros -> UserEntry.Sources.OmnipodEros
|
PumpType.Source.OmnipodEros -> UserEntry.Sources.OmnipodEros
|
||||||
PumpType.Source.OmnipodDash -> UserEntry.Sources.OmnipodDash
|
PumpType.Source.OmnipodDash -> UserEntry.Sources.OmnipodDash
|
||||||
PumpType.Source.EOPatch2 -> UserEntry.Sources.EOPatch2
|
PumpType.Source.EOPatch2 -> UserEntry.Sources.EOPatch2
|
||||||
|
PumpType.Source.Medtrum -> UserEntry.Sources.Medtrum
|
||||||
PumpType.Source.MDI -> UserEntry.Sources.MDI
|
PumpType.Source.MDI -> UserEntry.Sources.MDI
|
||||||
PumpType.Source.VirtualPump -> UserEntry.Sources.VirtualPump
|
PumpType.Source.VirtualPump -> UserEntry.Sources.VirtualPump
|
||||||
else -> UserEntry.Sources.Unknown
|
else -> UserEntry.Sources.Unknown
|
||||||
|
@ -120,6 +122,7 @@ fun PumpType.toDbPumpType(): InterfaceIDs.PumpType =
|
||||||
PumpType.DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
|
PumpType.DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
|
||||||
PumpType.EOFLOW_EOPATCH2 -> InterfaceIDs.PumpType.EOPATCH2
|
PumpType.EOFLOW_EOPATCH2 -> InterfaceIDs.PumpType.EOPATCH2
|
||||||
PumpType.MEDTRUM_NANO -> InterfaceIDs.PumpType.MEDTRUM
|
PumpType.MEDTRUM_NANO -> InterfaceIDs.PumpType.MEDTRUM
|
||||||
|
PumpType.MEDTRUM_300U -> InterfaceIDs.PumpType.MEDTRUM_300U
|
||||||
PumpType.MEDTRUM_UNTESTED -> InterfaceIDs.PumpType.MEDTRUM_UNTESTED
|
PumpType.MEDTRUM_UNTESTED -> InterfaceIDs.PumpType.MEDTRUM_UNTESTED
|
||||||
PumpType.CACHE -> InterfaceIDs.PumpType.CACHE
|
PumpType.CACHE -> InterfaceIDs.PumpType.CACHE
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,14 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
|
||||||
holder.isDividerAllowedBelow = false
|
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 {
|
private fun obtainValidatorParameters(attrs: AttributeSet): DefaultEditTextValidator.Parameters {
|
||||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FormEditText, 0, 0)
|
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FormEditText, 0, 0)
|
||||||
return DefaultEditTextValidator.Parameters(
|
return DefaultEditTextValidator.Parameters(
|
||||||
|
|
|
@ -172,6 +172,7 @@ data class UserEntry(
|
||||||
OmnipodEros,
|
OmnipodEros,
|
||||||
OmnipodDash, //No entry currently
|
OmnipodDash, //No entry currently
|
||||||
EOPatch2,
|
EOPatch2,
|
||||||
|
Medtrum,
|
||||||
MDI,
|
MDI,
|
||||||
VirtualPump,
|
VirtualPump,
|
||||||
SMS, //From SMS plugin
|
SMS, //From SMS plugin
|
||||||
|
|
|
@ -44,6 +44,7 @@ data class InterfaceIDs(
|
||||||
DIACONN_G8,
|
DIACONN_G8,
|
||||||
EOPATCH2,
|
EOPATCH2,
|
||||||
MEDTRUM,
|
MEDTRUM,
|
||||||
|
MEDTRUM_300U,
|
||||||
MEDTRUM_UNTESTED,
|
MEDTRUM_UNTESTED,
|
||||||
USER,
|
USER,
|
||||||
CACHE;
|
CACHE;
|
||||||
|
|
|
@ -97,6 +97,7 @@ class UserEntryPresentationHelperImpl @Inject constructor(
|
||||||
Sources.OmnipodEros -> R.drawable.ic_patch_pump_outline
|
Sources.OmnipodEros -> R.drawable.ic_patch_pump_outline
|
||||||
Sources.OmnipodDash -> 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.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.MDI -> R.drawable.ic_ict
|
||||||
Sources.VirtualPump -> R.drawable.ic_virtual_pump
|
Sources.VirtualPump -> R.drawable.ic_virtual_pump
|
||||||
Sources.SMS -> R.drawable.ic_sms
|
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.dialogs.OKDialog
|
||||||
import info.nightscout.core.ui.toast.ToastUtils
|
import info.nightscout.core.ui.toast.ToastUtils
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
|
import info.nightscout.core.validators.ValidatingEditTextPreference
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.Constraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
|
@ -127,33 +128,41 @@ import kotlin.math.abs
|
||||||
|
|
||||||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||||
super.preprocessPreferences(preferenceFragment)
|
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))
|
val serialSetting = preferenceFragment.findPreference<EditTextPreference>(rh.gs(R.string.key_sn_input))
|
||||||
serialSetting?.isEnabled = !isInitialized()
|
serialSetting?.apply {
|
||||||
serialSetting?.setOnBindEditTextListener { editText ->
|
isEnabled = !isInitialized()
|
||||||
editText.addTextChangedListener(object : TextWatcher {
|
setOnBindEditTextListener { editText ->
|
||||||
override fun afterTextChanged(newValue: Editable?) {
|
editText.addTextChangedListener(object : TextWatcher {
|
||||||
val newSN = newValue.toString().toLongOrNull(radix = 16)
|
override fun afterTextChanged(newValue: Editable?) {
|
||||||
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN ?: 0)
|
val newSN = newValue?.toString()?.toLongOrNull(radix = 16) ?: 0
|
||||||
if (newDeviceType == MedtrumSnUtil.INVALID) {
|
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN)
|
||||||
editText.error = rh.gs(R.string.sn_input_invalid)
|
editText.error = if (newDeviceType == MedtrumSnUtil.INVALID) {
|
||||||
} else {
|
rh.gs(R.string.sn_input_invalid)
|
||||||
editText.error = null
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||||
// Nothing to do here
|
// 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 {
|
when {
|
||||||
newDeviceType == MedtrumSnUtil.INVALID -> {
|
newDeviceType == MedtrumSnUtil.INVALID -> {
|
||||||
preferenceFragment.activity?.let { activity ->
|
preferenceFragment.activity?.let { activity ->
|
||||||
|
@ -171,30 +180,61 @@ import kotlin.math.abs
|
||||||
|
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun preprocessAlarmSettings(preferenceFragment: PreferenceFragmentCompat) {
|
||||||
val alarmSetting = preferenceFragment.findPreference<ListPreference>(rh.gs(R.string.key_alarm_setting))
|
val alarmSetting = preferenceFragment.findPreference<ListPreference>(rh.gs(R.string.key_alarm_setting))
|
||||||
val allAlarmEntries = preferenceFragment.resources.getStringArray(R.array.alarmSettings)
|
val allAlarmEntries = preferenceFragment.resources.getStringArray(R.array.alarmSettings)
|
||||||
val allAlarmValues = preferenceFragment.resources.getStringArray(R.array.alarmSettingsValues)
|
val allAlarmValues = preferenceFragment.resources.getStringArray(R.array.alarmSettingsValues)
|
||||||
|
|
||||||
if (allAlarmEntries.size < 8 || allAlarmValues.size < 8) {
|
if (allAlarmEntries.size < 8 || allAlarmValues.size < 8) {
|
||||||
aapsLogger.error(LTag.PUMP, "Alarm settings array is not complete")
|
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()) {
|
hourlyMaxSetting?.apply {
|
||||||
PumpType.MEDTRUM_NANO -> {
|
setMaxNumber(pumpTypeSettings.first)
|
||||||
alarmSetting?.entries = arrayOf(allAlarmEntries[6], allAlarmEntries[7]) // "Beep", "Silent"
|
val hourlyCurrentValue = text?.toIntOrNull() ?: 0
|
||||||
alarmSetting?.entryValues = arrayOf(allAlarmValues[6], allAlarmValues[7]) // "6", "7"
|
if (hourlyCurrentValue > pumpTypeSettings.first) {
|
||||||
|
text = pumpTypeSettings.first.toString()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
dailyMaxSetting?.apply {
|
||||||
// Use Nano settings for unknown pumps
|
setMaxNumber(pumpTypeSettings.second)
|
||||||
alarmSetting?.entries = arrayOf(allAlarmEntries[6], allAlarmEntries[7]) // "Beep", "Silent"
|
val dailyCurrentValue = text?.toIntOrNull() ?: 0
|
||||||
alarmSetting?.entryValues = arrayOf(allAlarmValues[6], allAlarmValues[7]) // "6", "7"
|
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 isHandshakeInProgress(): Boolean = false
|
||||||
|
|
||||||
override fun finishHandshaking() {
|
override fun finishHandshaking() {
|
||||||
|
// Unused
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun connect(reason: String) {
|
override fun connect(reason: String) {
|
||||||
|
@ -417,6 +458,7 @@ import kotlin.math.abs
|
||||||
try {
|
try {
|
||||||
extended.put("ActiveProfile", profileName)
|
extended.put("ActiveProfile", profileName)
|
||||||
} catch (ignored: Exception) {
|
} catch (ignored: Exception) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
pumpJson.put("status", status)
|
pumpJson.put("status", status)
|
||||||
pumpJson.put("extended", extended)
|
pumpJson.put("extended", extended)
|
||||||
|
@ -472,6 +514,7 @@ import kotlin.math.abs
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun executeCustomAction(customActionType: CustomActionType) {
|
override fun executeCustomAction(customActionType: CustomActionType) {
|
||||||
|
// Unused
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? {
|
override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.pump.medtrum
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
|
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||||
import info.nightscout.interfaces.pump.defs.PumpType
|
import info.nightscout.interfaces.pump.defs.PumpType
|
||||||
|
@ -294,6 +295,7 @@ class MedtrumPump @Inject constructor(
|
||||||
fun pumpType(type: Int): PumpType =
|
fun pumpType(type: Int): PumpType =
|
||||||
when (type) {
|
when (type) {
|
||||||
MedtrumSnUtil.MD_0201, MedtrumSnUtil.MD_8201 -> PumpType.MEDTRUM_NANO
|
MedtrumSnUtil.MD_0201, MedtrumSnUtil.MD_8201 -> PumpType.MEDTRUM_NANO
|
||||||
|
MedtrumSnUtil.MD_8301 -> PumpType.MEDTRUM_300U
|
||||||
else -> PumpType.MEDTRUM_UNTESTED
|
else -> PumpType.MEDTRUM_UNTESTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +335,7 @@ class MedtrumPump @Inject constructor(
|
||||||
|
|
||||||
val date = GregorianCalendar()
|
val date = GregorianCalendar()
|
||||||
date.timeInMillis = timestamp
|
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) {
|
for (index in 0 until basalCount) {
|
||||||
val currentIndex = 1 + (index * 3)
|
val currentIndex = 1 + (index * 3)
|
||||||
|
@ -354,7 +356,6 @@ class MedtrumPump @Inject constructor(
|
||||||
aapsLogger.debug(LTag.PUMP, "getHourlyBasalFromMedtrumProfileArray: basal: $basal")
|
aapsLogger.debug(LTag.PUMP, "getHourlyBasalFromMedtrumProfileArray: basal: $basal")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// aapsLogger.debug(LTag.PUMP, "getHourlyBasalFromMedtrumProfileArray: rate: $rate, startMinutes: $startMinutes, endMinutes: $endMinutes")
|
|
||||||
}
|
}
|
||||||
return basal
|
return basal
|
||||||
}
|
}
|
||||||
|
@ -378,59 +379,67 @@ class MedtrumPump @Inject constructor(
|
||||||
)
|
)
|
||||||
@Suppress("UNNECESSARY_SAFE_CALL") // Safe call to allow mocks to return null
|
@Suppress("UNNECESSARY_SAFE_CALL") // Safe call to allow mocks to return null
|
||||||
val expectedTemporaryBasal = pumpSync.expectedPumpState()?.temporaryBasal
|
val expectedTemporaryBasal = pumpSync.expectedPumpState()?.temporaryBasal
|
||||||
if (basalType.isTempBasal() && expectedTemporaryBasal?.pumpId != basalStartTime) {
|
when {
|
||||||
// Note: temporaryBasalInfo will be removed from temporaryBasalStorage after this call
|
basalType.isTempBasal() && expectedTemporaryBasal?.pumpId != basalStartTime -> {
|
||||||
val temporaryBasalInfo = temporaryBasalStorage.findTemporaryBasal(basalStartTime, basalRate)
|
// 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
|
// 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 duration = temporaryBasalInfo?.duration ?: T.mins(FAKE_TBR_LENGTH).msecs()
|
||||||
val adjustedBasalRate = if (basalType == BasalType.ABSOLUTE_TEMP) {
|
val adjustedBasalRate = if (basalType == BasalType.ABSOLUTE_TEMP) {
|
||||||
basalRate
|
basalRate
|
||||||
} else {
|
} else {
|
||||||
(basalRate / baseBasalRate) * 100 // calculate the percentage of the original basal rate
|
(basalRate / baseBasalRate) * 100 // calculate the percentage of the original basal rate
|
||||||
}
|
}
|
||||||
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
val newRecord = pumpSync.syncTemporaryBasalWithPumpId(
|
||||||
timestamp = basalStartTime,
|
timestamp = basalStartTime,
|
||||||
rate = adjustedBasalRate,
|
rate = adjustedBasalRate,
|
||||||
duration = duration,
|
duration = duration,
|
||||||
isAbsolute = (basalType == BasalType.ABSOLUTE_TEMP),
|
isAbsolute = (basalType == BasalType.ABSOLUTE_TEMP),
|
||||||
type = temporaryBasalInfo?.type,
|
type = temporaryBasalInfo?.type,
|
||||||
pumpId = basalStartTime,
|
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
|
|
||||||
pumpType = pumpType(),
|
pumpType = pumpType(),
|
||||||
pumpSerial = pumpSN.toString(radix = 16)
|
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)
|
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() {
|
private fun saveActiveAlarms() {
|
||||||
val alarmsStr = activeAlarms.joinToString(separator = ",") { it.name }
|
val alarmsStr = activeAlarms.joinToString(separator = ",") { it.name }
|
||||||
sp.putString(R.string.key_active_alarms, alarmsStr)
|
sp.putString(R.string.key_active_alarms, alarmsStr)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package info.nightscout.pump.medtrum.comm.packets
|
package info.nightscout.pump.medtrum.comm.packets
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
import info.nightscout.pump.medtrum.MedtrumPump
|
import info.nightscout.pump.medtrum.MedtrumPump
|
||||||
import info.nightscout.pump.medtrum.comm.enums.CommandType.ACTIVATE
|
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 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())
|
val basalStartTime = medtrumTimeUtil.convertPumpTimeToSystemTimeMillis(data.copyOfRange(RESP_BASAL_START_TIME_START, RESP_BASAL_START_TIME_END).toLong())
|
||||||
|
|
||||||
medtrumPump.patchId = patchId
|
|
||||||
medtrumPump.lastTimeReceivedFromPump = time
|
medtrumPump.lastTimeReceivedFromPump = time
|
||||||
medtrumPump.currentSequenceNumber = basalSequence // We are activated, set the new seq nr
|
medtrumPump.handleNewPatch(patchId, basalSequence, System.currentTimeMillis())
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update the actual basal profile
|
// Update the actual basal profile
|
||||||
medtrumPump.actualBasalProfile = basalProfile
|
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"
|
"$bolusExtendedDuration, " + "bolusExtendedDelivered: $bolusExtendedDelivered, bolusCarb: $bolusCarb, bolusGlucose: $bolusGlucose, bolusIOB: $bolusIOB, unknown1: $unknown1, unknown2: $unknown2, " + "bolusType: $bolusType, bolusWizard: $bolusWizard"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (bolusType == BolusType.NORMAL) {
|
when (bolusType) {
|
||||||
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
BolusType.NORMAL -> {
|
||||||
var newRecord = false
|
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||||
if (detailedBolusInfo != null) {
|
var newRecord = false
|
||||||
val syncOk = pumpSync.syncBolusWithTempId(
|
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,
|
timestamp = bolusStartTime,
|
||||||
amount = bolusNormalDelivered,
|
amount = bolusExtendedDelivered,
|
||||||
temporaryId = detailedBolusInfo.timestamp,
|
duration = bolusExtendedDuration,
|
||||||
type = detailedBolusInfo.bolusType,
|
isEmulatingTB = false,
|
||||||
pumpId = bolusStartTime,
|
pumpId = bolusStartTime,
|
||||||
pumpType = medtrumPump.pumpType(),
|
pumpType = medtrumPump.pumpType(),
|
||||||
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
|
||||||
)
|
)
|
||||||
if (!syncOk) {
|
aapsLogger.debug(
|
||||||
aapsLogger.warn(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Failed to sync bolus with tempId: ${detailedBolusInfo.timestamp}")
|
LTag.PUMPCOMM,
|
||||||
// detailedInfo can be from another similar record. Reinsert
|
"from record: ${if (newRecord) "**NEW** " else ""}EVENT EXTENDED BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
||||||
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(
|
BolusType.COMBI -> {
|
||||||
LTag.PUMPCOMM,
|
// Note, this should never happen, as we don't use combo bolus
|
||||||
"from record: ${if (newRecord) "**NEW** " else ""}EVENT BOLUS ${dateUtil.dateAndTimeString(bolusStartTime)} ($bolusStartTime) Bolus: ${bolusNormalDelivered}U "
|
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
|
||||||
)
|
val newRecord = pumpSync.syncBolusWithPumpId(
|
||||||
if (bolusStartTime > medtrumPump.lastBolusTime) {
|
timestamp = bolusStartTime,
|
||||||
medtrumPump.lastBolusTime = bolusStartTime
|
amount = bolusNormalDelivered,
|
||||||
medtrumPump.lastBolusAmount = 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(
|
else -> {
|
||||||
timestamp = bolusStartTime,
|
aapsLogger.error(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Unknown bolus type: $bolusType")
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
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) {
|
fun handleMaskedMessage(data: ByteArray) {
|
||||||
val fieldMask = data.copyOfRange(0, 2).toInt()
|
val fieldMask = data.copyOfRange(0, 2).toInt()
|
||||||
var offset = 2
|
var offset = 2
|
||||||
|
var newPatchStartTime: Long? = null
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Message field mask: $fieldMask")
|
aapsLogger.debug(LTag.PUMPCOMM, "Message field mask: $fieldMask")
|
||||||
|
|
||||||
|
@ -148,12 +149,12 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
||||||
|
|
||||||
if (fieldMask and MASK_START_TIME != 0) {
|
if (fieldMask and MASK_START_TIME != 0) {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Start time notification received")
|
aapsLogger.debug(LTag.PUMPCOMM, "Start time notification received")
|
||||||
val patchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset, offset + 4).toLong())
|
newPatchStartTime = MedtrumTimeUtil().convertPumpTimeToSystemTimeMillis(data.copyOfRange(offset, offset + 4).toLong())
|
||||||
if (medtrumPump.patchStartTime != patchStartTime) {
|
if (medtrumPump.patchStartTime != newPatchStartTime) {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time changed from ${medtrumPump.patchStartTime} to $patchStartTime")
|
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time changed from ${medtrumPump.patchStartTime} to $newPatchStartTime")
|
||||||
medtrumPump.patchStartTime = patchStartTime
|
medtrumPump.patchStartTime = newPatchStartTime
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time: ${patchStartTime}")
|
aapsLogger.debug(LTag.PUMPCOMM, "Patch start time: $newPatchStartTime")
|
||||||
offset += 4
|
offset += 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +177,11 @@ class NotificationPacket(val injector: HasAndroidInjector) {
|
||||||
val patchId = data.copyOfRange(offset + 2, offset + 4).toLong()
|
val patchId = data.copyOfRange(offset + 2, offset + 4).toLong()
|
||||||
if (patchId != medtrumPump.patchId) {
|
if (patchId != medtrumPump.patchId) {
|
||||||
aapsLogger.warn(LTag.PUMPCOMM, "handleMaskedMessage: We got wrong patch id!")
|
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}")
|
aapsLogger.debug(LTag.PUMPCOMM, "Last known sequence number: ${medtrumPump.currentSequenceNumber}, patch id: ${patchId}")
|
||||||
offset += 4
|
offset += 4
|
||||||
|
|
|
@ -39,11 +39,11 @@ class Crypt {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun randomGen(input: Long): Long {
|
private fun randomGen(input: Long): Long {
|
||||||
val A = 16807
|
val a = 16807
|
||||||
val Q = 127773
|
val q = 127773
|
||||||
val R = 2836
|
val r = 2836
|
||||||
val tmp1 = input / Q
|
val tmp1 = input / q
|
||||||
var ret = (input - (tmp1 * Q)) * A - (tmp1 * R)
|
var ret = (input - (tmp1 * q)) * a - (tmp1 * r)
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret += 2147483647L
|
ret += 2147483647L
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,9 +310,7 @@ class BLEComm @Inject internal constructor(
|
||||||
private fun readDescriptor(descriptor: BluetoothGattDescriptor?) {
|
private fun readDescriptor(descriptor: BluetoothGattDescriptor?) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "readDescriptor")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "readDescriptor")
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null || descriptor == null) {
|
if (mBluetoothAdapter == null || mBluetoothGatt == null || descriptor == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
handleNotInitialized()
|
||||||
isConnecting = false
|
|
||||||
isConnected = false
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mBluetoothGatt?.readDescriptor(descriptor)
|
mBluetoothGatt?.readDescriptor(descriptor)
|
||||||
|
@ -323,9 +321,7 @@ class BLEComm @Inject internal constructor(
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "checkDescriptor")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "checkDescriptor")
|
||||||
val service = getGattService()
|
val service = getGattService()
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null || service == null) {
|
if (mBluetoothAdapter == null || mBluetoothGatt == null || service == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
handleNotInitialized()
|
||||||
isConnecting = false
|
|
||||||
isConnected = false
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (descriptor.value.toInt() > 0) {
|
if (descriptor.value.toInt() > 0) {
|
||||||
|
@ -352,9 +348,7 @@ class BLEComm @Inject internal constructor(
|
||||||
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
|
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
handleNotInitialized()
|
||||||
isConnecting = false
|
|
||||||
isConnected = false
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mBluetoothGatt?.setCharacteristicNotification(characteristic, enabled)
|
mBluetoothGatt?.setCharacteristicNotification(characteristic, enabled)
|
||||||
|
@ -366,7 +360,7 @@ class BLEComm @Inject internal constructor(
|
||||||
it.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
|
it.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
|
||||||
mBluetoothGatt?.writeDescriptor(it)
|
mBluetoothGatt?.writeDescriptor(it)
|
||||||
} else {
|
} else {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,9 +411,7 @@ class BLEComm @Inject internal constructor(
|
||||||
private fun getGattService(): BluetoothGattService? {
|
private fun getGattService(): BluetoothGattService? {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "getGattService")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "getGattService")
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
handleNotInitialized()
|
||||||
isConnecting = false
|
|
||||||
isConnected = false
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return mBluetoothGatt?.getService(UUID.fromString(SERVICE_UUID))
|
return mBluetoothGatt?.getService(UUID.fromString(SERVICE_UUID))
|
||||||
|
@ -431,9 +423,7 @@ class BLEComm @Inject internal constructor(
|
||||||
private fun writeCharacteristic(characteristic: BluetoothGattCharacteristic, data: ByteArray?) {
|
private fun writeCharacteristic(characteristic: BluetoothGattCharacteristic, data: ByteArray?) {
|
||||||
handler.postDelayed({
|
handler.postDelayed({
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
handleNotInitialized()
|
||||||
isConnecting = false
|
|
||||||
isConnected = false
|
|
||||||
} else {
|
} else {
|
||||||
characteristic.value = data
|
characteristic.value = data
|
||||||
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
|
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
|
||||||
|
@ -456,7 +446,7 @@ class BLEComm @Inject internal constructor(
|
||||||
var uuid: String
|
var uuid: String
|
||||||
val gattCharacteristics = gattService.characteristics
|
val gattCharacteristics = gattService.characteristics
|
||||||
for (i in 0 until gattCharacteristics.size) {
|
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
|
// 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) {
|
if (gattCharacteristic.properties and NEEDS_ENABLE > 0) {
|
||||||
handler.postDelayed({
|
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)
|
}, fabricPrivacy::logException)
|
||||||
scope.launch {
|
scope.launch {
|
||||||
medtrumPump.pumpStateFlow.collect { state ->
|
medtrumPump.pumpStateFlow.collect { pumpState ->
|
||||||
handlePumpStateUpdate(state)
|
handlePumpStateUpdate(pumpState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.launch {
|
scope.launch {
|
||||||
medtrumPump.connectionStateFlow.collect { state ->
|
medtrumPump.connectionStateFlow.collect { connectionState ->
|
||||||
if (medtrumPlugin.isInitialized()) {
|
handleConnectionStateChange(connectionState)
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,23 +156,29 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
|
|
||||||
fun connect(from: String): Boolean {
|
fun connect(from: String): Boolean {
|
||||||
aapsLogger.debug(LTag.PUMP, "connect: called from: $from")
|
aapsLogger.debug(LTag.PUMP, "connect: called from: $from")
|
||||||
if (currentState is IdleState) {
|
when (currentState) {
|
||||||
medtrumPump.connectionState = ConnectionState.CONNECTING
|
is IdleState -> {
|
||||||
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())
|
|
||||||
medtrumPump.connectionState = ConnectionState.CONNECTING
|
medtrumPump.connectionState = ConnectionState.CONNECTING
|
||||||
return bleComm.connect(from, medtrumPump.pumpSN)
|
return bleComm.connect(from, medtrumPump.pumpSN)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in state: $currentState from: $from")
|
is ReadyState -> {
|
||||||
return false
|
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)
|
timeUpdateNotification(result)
|
||||||
}
|
}
|
||||||
// Do this here, because TBR can be cancelled due to time change by connect flow
|
// Do this here, because TBR can be cancelled due to time change by connect flow
|
||||||
if (needLoadHistory) {
|
if (needLoadHistory && result) {
|
||||||
if (result) result = loadEvents()
|
result = loadEvents()
|
||||||
}
|
}
|
||||||
if (result) medtrumPump.needCheckTimeUpdate = false
|
if (result) medtrumPump.needCheckTimeUpdate = false
|
||||||
return result
|
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 */
|
/** BLECommCallbacks */
|
||||||
override fun onBLEConnected() {
|
override fun onBLEConnected() {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onBLEConnected")
|
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onBLEConnected")
|
||||||
|
@ -676,7 +686,10 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
protected var responseSuccess = false
|
protected var responseSuccess = false
|
||||||
protected var sendRetryCounter = 0
|
protected var sendRetryCounter = 0
|
||||||
|
|
||||||
open fun onEnter() {}
|
open fun onEnter() {
|
||||||
|
// Used when a state is entered
|
||||||
|
}
|
||||||
|
|
||||||
open fun onIndication(data: ByteArray) {
|
open fun onIndication(data: ByteArray) {
|
||||||
aapsLogger.warn(LTag.PUMPCOMM, "onIndication: " + this.toString() + "Should not be called here!")
|
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.pump.medtrum.ui.event.UIEvent
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.interfaces.queue.CommandQueue
|
import info.nightscout.interfaces.queue.CommandQueue
|
||||||
|
import info.nightscout.pump.medtrum.MedtrumPlugin
|
||||||
import info.nightscout.pump.medtrum.MedtrumPump
|
import info.nightscout.pump.medtrum.MedtrumPump
|
||||||
import info.nightscout.pump.medtrum.R
|
import info.nightscout.pump.medtrum.R
|
||||||
import info.nightscout.pump.medtrum.code.ConnectionState
|
import info.nightscout.pump.medtrum.code.ConnectionState
|
||||||
|
@ -28,6 +29,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val commandQueue: CommandQueue,
|
private val commandQueue: CommandQueue,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
|
private val medtrumPlugin: MedtrumPlugin,
|
||||||
val medtrumPump: MedtrumPump
|
val medtrumPump: MedtrumPump
|
||||||
) : BaseViewModel<MedtrumBaseNavigator>() {
|
) : BaseViewModel<MedtrumBaseNavigator>() {
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
||||||
scope.launch {
|
scope.launch {
|
||||||
medtrumPump.bolusAmountDeliveredFlow.collect { bolusAmount ->
|
medtrumPump.bolusAmountDeliveredFlow.collect { bolusAmount ->
|
||||||
aapsLogger.debug(LTag.PUMP, "MedtrumViewModel bolusAmountDeliveredFlow: $bolusAmount")
|
aapsLogger.debug(LTag.PUMP, "MedtrumViewModel bolusAmountDeliveredFlow: $bolusAmount")
|
||||||
if (!medtrumPump.bolusDone) {
|
if (!medtrumPump.bolusDone && medtrumPlugin.isInitialized()) {
|
||||||
_activeBolusStatus.postValue(
|
_activeBolusStatus.postValue(
|
||||||
dateUtil.timeString(medtrumPump.bolusStartTime) + " " + dateUtil.sinceString(medtrumPump.bolusStartTime, rh)
|
dateUtil.timeString(medtrumPump.bolusStartTime) + " " + dateUtil.sinceString(medtrumPump.bolusStartTime, rh)
|
||||||
+ " " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, bolusAmount) + " / " + rh.gs(
|
+ " " + 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())
|
kotlinx.coroutines.delay(T.mins(1).msecs())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Update gui on init
|
||||||
|
updateGUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
@ -189,7 +193,7 @@ class MedtrumOverviewViewModel @Inject constructor(
|
||||||
)
|
)
|
||||||
else _lastBolus.postValue("")
|
else _lastBolus.postValue("")
|
||||||
}
|
}
|
||||||
if (medtrumPump.bolusDone) {
|
if (medtrumPump.bolusDone || !medtrumPlugin.isInitialized()) {
|
||||||
_activeBolusStatus.postValue("")
|
_activeBolusStatus.postValue("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ class MedtrumViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState.CONNECTING, ConnectionState.DISCONNECTING -> {
|
ConnectionState.CONNECTING, ConnectionState.DISCONNECTING -> {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class ViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {
|
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 {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
var creator: Provider<out ViewModel>? = creators[modelClass]
|
var creator: Provider<out ViewModel>? = creators[modelClass]
|
||||||
if (creator == null) {
|
if (creator == null) {
|
||||||
|
@ -26,9 +27,7 @@ class ViewModelFactory @Inject constructor(private val creators: Map<Class<out V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (creator == null) {
|
requireNotNull(creator) { "unknown model class $modelClass" }
|
||||||
throw IllegalArgumentException("unknown model class $modelClass")
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return creator.get() as T
|
return creator.get() as T
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
<string name="medtrum">Medtrum</string>
|
<string name="medtrum">Medtrum</string>
|
||||||
<string name="medtrum_pump_shortname">MT</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="medtrum_pump_setting">Medtrum pump settings</string>
|
||||||
<string name="pump_error">Pump error: %1$s !! </string>
|
<string name="pump_error">Pump error: %1$s !! </string>
|
||||||
<string name="pump_is_suspended">Pump is suspended</string>
|
<string name="pump_is_suspended">Pump is suspended</string>
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
android:title="@string/daily_max_insulin_title"
|
android:title="@string/daily_max_insulin_title"
|
||||||
android:dialogMessage="@string/daily_max_insulin_summary"
|
android:dialogMessage="@string/daily_max_insulin_summary"
|
||||||
validate:maxNumber="180"
|
validate:maxNumber="180"
|
||||||
validate:minNumber="25"
|
validate:minNumber="20"
|
||||||
validate:testType="numericRange" />
|
validate:testType="numericRange" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
Loading…
Reference in a new issue