Merge pull request #2683 from jbr7rr/medtrum-improvements

Medtrum: Handle pumpType when SN is entered
This commit is contained in:
Milos Kozak 2023-08-20 08:04:30 +02:00 committed by GitHub
commit b5a47af79a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 124 additions and 47 deletions

View file

@ -5,11 +5,14 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.os.IBinder import android.os.IBinder
import android.text.Editable
import android.text.TextWatcher
import android.text.format.DateFormat import android.text.format.DateFormat
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
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.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
@ -39,6 +42,7 @@ import info.nightscout.interfaces.utils.TimeChangeType
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment
import info.nightscout.pump.medtrum.services.MedtrumService import info.nightscout.pump.medtrum.services.MedtrumService
import info.nightscout.pump.medtrum.util.MedtrumSnUtil
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit import info.nightscout.rx.events.EventAppExit
@ -123,7 +127,54 @@ import kotlin.math.abs
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) { override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
super.preprocessPreferences(preferenceFragment) super.preprocessPreferences(preferenceFragment)
preferenceFragment.findPreference<EditTextPreference>(rh.gs(R.string.key_sn_input))?.isEnabled = !isInitialized() val serialSetting = preferenceFragment.findPreference<EditTextPreference>(rh.gs(R.string.key_sn_input))
serialSetting?.isEnabled = !isInitialized()
serialSetting?.setOnBindEditTextListener { editText ->
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(newValue: Editable?) {
val newSN = newValue.toString().toLongOrNull(radix = 16)
val newDeviceType = MedtrumSnUtil().getDeviceTypeFromSerial(newSN ?: 0)
if (newDeviceType == MedtrumSnUtil.INVALID) {
editText.error = rh.gs(R.string.sn_input_invalid)
} else {
editText.error = null
}
}
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
}
})
}
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 ->
OKDialog.show(activity, rh.gs(R.string.sn_input_title), rh.gs(R.string.sn_input_invalid))
}
false
}
medtrumPump.pumpType(newDeviceType) == PumpType.MEDTRUM_UNTESTED -> {
preferenceFragment.activity?.let { activity ->
OKDialog.show(activity, rh.gs(R.string.sn_input_title), rh.gs(R.string.pump_unsupported, newDeviceType))
}
false
}
else -> true
}
} else {
false
}
}
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)

View file

@ -12,6 +12,7 @@ import info.nightscout.pump.medtrum.comm.enums.BasalType
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
import info.nightscout.pump.medtrum.extension.toByteArray import info.nightscout.pump.medtrum.extension.toByteArray
import info.nightscout.pump.medtrum.extension.toInt import info.nightscout.pump.medtrum.extension.toInt
import info.nightscout.pump.medtrum.util.MedtrumSnUtil
import info.nightscout.rx.events.EventOverviewBolusProgress import info.nightscout.rx.events.EventOverviewBolusProgress
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
@ -170,7 +171,7 @@ class MedtrumPump @Inject constructor(
sp.putLong(R.string.key_last_connection, value) sp.putLong(R.string.key_last_connection, value)
} }
private var _deviceType: Int = 80 // As reported by pump private var _deviceType: Int = 0 // As reported by pump
var deviceType: Int var deviceType: Int
get() = _deviceType get() = _deviceType
set(value) { set(value) {
@ -280,14 +281,16 @@ class MedtrumPump @Inject constructor(
try { try {
_actualBasalProfile = Base64.decode(encodedString, Base64.DEFAULT) _actualBasalProfile = Base64.decode(encodedString, Base64.DEFAULT)
} catch (e: Exception) { } catch (e: Exception) {
aapsLogger.error(LTag.PUMP, "Error decoding basal profile from SP: $encodedString") aapsLogger.warn(LTag.PUMP, "Error decoding basal profile from SP: $encodedString")
} }
} }
fun pumpType(): PumpType = fun pumpType(): PumpType = pumpType(deviceType)
when (deviceType) {
80, 88 -> PumpType.MEDTRUM_NANO fun pumpType(type: Int): PumpType =
else -> PumpType.MEDTRUM_UNTESTED when (type) {
MedtrumSnUtil.MD_0201, MedtrumSnUtil.MD_8201 -> PumpType.MEDTRUM_NANO
else -> PumpType.MEDTRUM_UNTESTED
} }
fun loadUserSettingsFromSP() { fun loadUserSettingsFromSP() {

View file

@ -45,6 +45,7 @@ class AuthorizePacket(injector: HasAndroidInjector) : MedtrumPacket(injector) {
).toInt() ).toInt()
if (medtrumPump.deviceType != deviceType) { if (medtrumPump.deviceType != deviceType) {
aapsLogger.warn(LTag.PUMPCOMM, "GetDeviceTypeState: deviceType changed from ${medtrumPump.deviceType} to $deviceType")
medtrumPump.deviceType = deviceType medtrumPump.deviceType = deviceType
} }
if (medtrumPump.swVersion != swVersion) { if (medtrumPump.swVersion != swVersion) {

View file

@ -29,6 +29,7 @@ import info.nightscout.pump.medtrum.code.ConnectionState
import info.nightscout.pump.medtrum.comm.enums.AlarmState import info.nightscout.pump.medtrum.comm.enums.AlarmState
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
import info.nightscout.pump.medtrum.comm.packets.* import info.nightscout.pump.medtrum.comm.packets.*
import info.nightscout.pump.medtrum.util.MedtrumSnUtil
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit import info.nightscout.rx.events.EventAppExit
@ -109,8 +110,9 @@ class MedtrumService : DaggerService(), BLECommCallback {
.subscribe({ event -> .subscribe({ event ->
if (event.isChanged(rh.gs(R.string.key_sn_input))) { if (event.isChanged(rh.gs(R.string.key_sn_input))) {
aapsLogger.debug(LTag.PUMPCOMM, "Serial number changed, reporting new pump!") aapsLogger.debug(LTag.PUMPCOMM, "Serial number changed, reporting new pump!")
pumpSync.connectNewPump()
medtrumPump.loadUserSettingsFromSP() medtrumPump.loadUserSettingsFromSP()
medtrumPump.deviceType = MedtrumSnUtil().getDeviceTypeFromSerial(medtrumPump.pumpSN)
pumpSync.connectNewPump()
medtrumPump.setFakeTBRIfNeeded() medtrumPump.setFakeTBRIfNeeded()
} }
if (event.isChanged(rh.gs(R.string.key_alarm_setting)) if (event.isChanged(rh.gs(R.string.key_alarm_setting))
@ -278,11 +280,11 @@ class MedtrumService : DaggerService(), BLECommCallback {
result = sendPacketAndGetResponse(ClearPumpAlarmPacket(injector, ALARM_HOURLY_MAX_CLEAR_CODE)) result = sendPacketAndGetResponse(ClearPumpAlarmPacket(injector, ALARM_HOURLY_MAX_CLEAR_CODE))
} }
MedtrumPumpState.DAILY_MAX_SUSPENDED -> { MedtrumPumpState.DAILY_MAX_SUSPENDED -> {
result = sendPacketAndGetResponse(ClearPumpAlarmPacket(injector, ALARM_DAILY_MAX_CLEAR_CODE)) result = sendPacketAndGetResponse(ClearPumpAlarmPacket(injector, ALARM_DAILY_MAX_CLEAR_CODE))
} }
else -> { else -> {
// Nothing to reset // Nothing to reset
} }
} }
@ -488,23 +490,23 @@ class MedtrumService : DaggerService(), BLECommCallback {
private fun handlePumpStateUpdate(state: MedtrumPumpState) { private fun handlePumpStateUpdate(state: MedtrumPumpState) {
// Map the pump state to an alarm state and add it to the active alarms // Map the pump state to an alarm state and add it to the active alarms
val alarmState = when (state) { val alarmState = when (state) {
MedtrumPumpState.NONE -> AlarmState.NONE MedtrumPumpState.NONE -> AlarmState.NONE
MedtrumPumpState.LOW_BG_SUSPENDED -> AlarmState.LOW_BG_SUSPENDED MedtrumPumpState.LOW_BG_SUSPENDED -> AlarmState.LOW_BG_SUSPENDED
MedtrumPumpState.LOW_BG_SUSPENDED2 -> AlarmState.LOW_BG_SUSPENDED2 MedtrumPumpState.LOW_BG_SUSPENDED2 -> AlarmState.LOW_BG_SUSPENDED2
MedtrumPumpState.AUTO_SUSPENDED -> AlarmState.AUTO_SUSPENDED MedtrumPumpState.AUTO_SUSPENDED -> AlarmState.AUTO_SUSPENDED
MedtrumPumpState.HOURLY_MAX_SUSPENDED -> AlarmState.HOURLY_MAX_SUSPENDED MedtrumPumpState.HOURLY_MAX_SUSPENDED -> AlarmState.HOURLY_MAX_SUSPENDED
MedtrumPumpState.DAILY_MAX_SUSPENDED -> AlarmState.DAILY_MAX_SUSPENDED MedtrumPumpState.DAILY_MAX_SUSPENDED -> AlarmState.DAILY_MAX_SUSPENDED
MedtrumPumpState.SUSPENDED -> AlarmState.SUSPENDED MedtrumPumpState.SUSPENDED -> AlarmState.SUSPENDED
MedtrumPumpState.PAUSED -> AlarmState.PAUSED MedtrumPumpState.PAUSED -> AlarmState.PAUSED
MedtrumPumpState.OCCLUSION -> AlarmState.OCCLUSION MedtrumPumpState.OCCLUSION -> AlarmState.OCCLUSION
MedtrumPumpState.EXPIRED -> AlarmState.EXPIRED MedtrumPumpState.EXPIRED -> AlarmState.EXPIRED
MedtrumPumpState.RESERVOIR_EMPTY -> AlarmState.RESERVOIR_EMPTY MedtrumPumpState.RESERVOIR_EMPTY -> AlarmState.RESERVOIR_EMPTY
MedtrumPumpState.PATCH_FAULT -> AlarmState.PATCH_FAULT MedtrumPumpState.PATCH_FAULT -> AlarmState.PATCH_FAULT
MedtrumPumpState.PATCH_FAULT2 -> AlarmState.PATCH_FAULT2 MedtrumPumpState.PATCH_FAULT2 -> AlarmState.PATCH_FAULT2
MedtrumPumpState.BASE_FAULT -> AlarmState.BASE_FAULT MedtrumPumpState.BASE_FAULT -> AlarmState.BASE_FAULT
MedtrumPumpState.BATTERY_OUT -> AlarmState.BATTERY_OUT MedtrumPumpState.BATTERY_OUT -> AlarmState.BATTERY_OUT
MedtrumPumpState.NO_CALIBRATION -> AlarmState.NO_CALIBRATION MedtrumPumpState.NO_CALIBRATION -> AlarmState.NO_CALIBRATION
else -> null else -> null
} }
if (alarmState != null && alarmState != AlarmState.NONE) { if (alarmState != null && alarmState != AlarmState.NONE) {
medtrumPump.addAlarm(alarmState) medtrumPump.addAlarm(alarmState)
@ -519,7 +521,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
// Map the pump state to a notification // Map the pump state to a notification
when (state) { when (state) {
MedtrumPumpState.NONE, MedtrumPumpState.NONE,
MedtrumPumpState.STOPPED -> { MedtrumPumpState.STOPPED -> {
rxBus.send(EventDismissNotification(Notification.PUMP_ERROR)) rxBus.send(EventDismissNotification(Notification.PUMP_ERROR))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
uiInteraction.addNotification( uiInteraction.addNotification(
@ -536,7 +538,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
MedtrumPumpState.PRIMING, MedtrumPumpState.PRIMING,
MedtrumPumpState.PRIMED, MedtrumPumpState.PRIMED,
MedtrumPumpState.EJECTING, MedtrumPumpState.EJECTING,
MedtrumPumpState.EJECTED -> { MedtrumPumpState.EJECTED -> {
rxBus.send(EventDismissNotification(Notification.PUMP_ERROR)) rxBus.send(EventDismissNotification(Notification.PUMP_ERROR))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
medtrumPump.setFakeTBRIfNeeded() medtrumPump.setFakeTBRIfNeeded()
@ -544,7 +546,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
} }
MedtrumPumpState.ACTIVE, MedtrumPumpState.ACTIVE,
MedtrumPumpState.ACTIVE_ALT -> { MedtrumPumpState.ACTIVE_ALT -> {
rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE)) rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
medtrumPump.clearAlarmState() medtrumPump.clearAlarmState()
@ -554,7 +556,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
MedtrumPumpState.LOW_BG_SUSPENDED2, MedtrumPumpState.LOW_BG_SUSPENDED2,
MedtrumPumpState.AUTO_SUSPENDED, MedtrumPumpState.AUTO_SUSPENDED,
MedtrumPumpState.SUSPENDED, MedtrumPumpState.SUSPENDED,
MedtrumPumpState.PAUSED -> { MedtrumPumpState.PAUSED -> {
uiInteraction.addNotification( uiInteraction.addNotification(
Notification.PUMP_SUSPENDED, Notification.PUMP_SUSPENDED,
rh.gs(R.string.pump_is_suspended), rh.gs(R.string.pump_is_suspended),
@ -572,7 +574,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
// Pump will report proper TBR for this // Pump will report proper TBR for this
} }
MedtrumPumpState.DAILY_MAX_SUSPENDED -> { MedtrumPumpState.DAILY_MAX_SUSPENDED -> {
uiInteraction.addNotification( uiInteraction.addNotification(
Notification.PUMP_SUSPENDED, Notification.PUMP_SUSPENDED,
rh.gs(R.string.pump_is_suspended_day_max), rh.gs(R.string.pump_is_suspended_day_max),
@ -588,7 +590,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
MedtrumPumpState.PATCH_FAULT2, MedtrumPumpState.PATCH_FAULT2,
MedtrumPumpState.BASE_FAULT, MedtrumPumpState.BASE_FAULT,
MedtrumPumpState.BATTERY_OUT, MedtrumPumpState.BATTERY_OUT,
MedtrumPumpState.NO_CALIBRATION -> { MedtrumPumpState.NO_CALIBRATION -> {
rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE)) rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
// Pump suspended due to error, show error! // Pump suspended due to error, show error!
@ -752,21 +754,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
// Success! // Success!
responseHandled = true responseHandled = true
responseSuccess = true responseSuccess = true
// Check if we have a supported pump toState(GetDeviceTypeState())
if (medtrumPump.pumpType() == PumpType.MEDTRUM_UNTESTED) {
// Throw error
aapsLogger.error(LTag.PUMPCOMM, "Unsupported pump type")
uiInteraction.addNotificationWithSound(
Notification.PUMP_ERROR,
rh.gs(R.string.pump_unsupported, medtrumPump.deviceType),
Notification.URGENT,
info.nightscout.core.ui.R.raw.alarm
)
disconnect("Unsupported pump")
toState(IdleState())
} else {
toState(GetDeviceTypeState())
}
} else if (mPacket?.failed == true) { } else if (mPacket?.failed == true) {
// Failure // Failure
responseHandled = true responseHandled = true

View file

@ -29,7 +29,7 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
title = getString(R.string.step_prepare_patch) title = getString(R.string.change_patch_label)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)

View file

@ -0,0 +1,33 @@
package info.nightscout.pump.medtrum.util
import info.nightscout.pump.medtrum.encryption.Crypt
class MedtrumSnUtil {
companion object {
const val INVALID = -1
const val MD_0201 = 80
const val MD_5201 = 81
const val MD_0202 = 82
const val MD_5202 = 83
const val MD_8201 = 88
const val MD_8301 = 98
}
fun getDeviceTypeFromSerial(serial: Long): Int {
if (serial in 106000000..106999999) {
return INVALID
}
return when (Crypt().simpleDecrypt(serial)) {
in 126000000..126999999 -> MD_0201
in 127000000..127999999 -> MD_5201
in 128000000..128999999 -> MD_8201
in 130000000..130999999 -> MD_0202
in 131000000..131999999 -> MD_5202
in 148000000..148999999 -> MD_8301
else -> INVALID
}
}
}

View file

@ -28,7 +28,6 @@
<string name="medtrum_pump_description">Pump integration for Medtrum Nano</string> <string name="medtrum_pump_description">Pump integration for Medtrum Nano</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_unsupported">Pump untested: %1$d! Please contact us at discord or github for support</string>
<string name="pump_is_suspended">Pump is suspended</string> <string name="pump_is_suspended">Pump is suspended</string>
<string name="pump_is_suspended_hour_max">Pump is suspended due to hourly max insulin exceeded</string> <string name="pump_is_suspended_hour_max">Pump is suspended due to hourly max insulin exceeded</string>
<string name="pump_is_suspended_day_max">Pump is suspended due to daily max insulin exceeded</string> <string name="pump_is_suspended_day_max">Pump is suspended due to daily max insulin exceeded</string>
@ -51,7 +50,7 @@
<string name="patch_expiry_label">Patch expires</string> <string name="patch_expiry_label">Patch expires</string>
<string name="refresh_label">Refresh</string> <string name="refresh_label">Refresh</string>
<string name="reset_alarms_label">Reset alarms</string> <string name="reset_alarms_label">Reset alarms</string>
<string name="change_patch_label">Change patch</string> <string name="change_patch_label">Change Patch</string>
<string name="requested_by_user" comment="26 characters max for translation">Requested by user</string> <string name="requested_by_user" comment="26 characters max for translation">Requested by user</string>
<string name="expiry_not_enabled">Not enabled</string> <string name="expiry_not_enabled">Not enabled</string>
@ -131,6 +130,8 @@
<!-- settings--> <!-- settings-->
<string name="sn_input_title">Serial Number</string> <string name="sn_input_title">Serial Number</string>
<string name="sn_input_summary">Enter the serial number of your pump base.</string> <string name="sn_input_summary">Enter the serial number of your pump base.</string>
<string name="sn_input_invalid">Invalid serial number!</string>
<string name="pump_unsupported">Pump untested: %1$d! Please contact us at discord or github for support</string>
<string name="alarm_setting_title">Alarm Settings</string> <string name="alarm_setting_title">Alarm Settings</string>
<string name="alarm_setting_summary">Select your preferred pump alarm settings.</string> <string name="alarm_setting_summary">Select your preferred pump alarm settings.</string>
<string name="patch_expiration_title">Patch Expiration</string> <string name="patch_expiration_title">Patch Expiration</string>