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 e9eb94d844..36acfcdda5 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 @@ -10,6 +10,7 @@ import androidx.preference.EditTextPreference import androidx.preference.ListPreference import androidx.preference.PreferenceFragmentCompat 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.interfaces.constraints.Constraint @@ -39,6 +40,7 @@ import info.nightscout.interfaces.utils.TimeChangeType import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment import info.nightscout.pump.medtrum.services.MedtrumService +import info.nightscout.pump.medtrum.util.MedtrumSnUtil import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventAppExit @@ -123,7 +125,33 @@ import kotlin.math.abs override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) { super.preprocessPreferences(preferenceFragment) - preferenceFragment.findPreference(rh.gs(R.string.key_sn_input))?.isEnabled = !isInitialized() + val serialSetting = preferenceFragment.findPreference(rh.gs(R.string.key_sn_input)) + serialSetting?.isEnabled = !isInitialized() + 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(rh.gs(R.string.key_alarm_setting)) val allAlarmEntries = preferenceFragment.resources.getStringArray(R.array.alarmSettings) 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 84b2c40150..0b814383cd 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 @@ -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.extension.toByteArray import info.nightscout.pump.medtrum.extension.toInt +import info.nightscout.pump.medtrum.util.MedtrumSnUtil import info.nightscout.rx.events.EventOverviewBolusProgress import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag @@ -170,7 +171,7 @@ class MedtrumPump @Inject constructor( 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 get() = _deviceType set(value) { @@ -280,14 +281,16 @@ class MedtrumPump @Inject constructor( try { _actualBasalProfile = Base64.decode(encodedString, Base64.DEFAULT) } 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 = - when (deviceType) { - 80, 88 -> PumpType.MEDTRUM_NANO - else -> PumpType.MEDTRUM_UNTESTED + fun pumpType(): PumpType = pumpType(deviceType) + + fun pumpType(type: Int): PumpType = + when (type) { + MedtrumSnUtil.MD_0201, MedtrumSnUtil.MD_8201 -> PumpType.MEDTRUM_NANO + else -> PumpType.MEDTRUM_UNTESTED } fun loadUserSettingsFromSP() { diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/AuthorizePacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/AuthorizePacket.kt index fce1d8c869..9eef408215 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/AuthorizePacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/AuthorizePacket.kt @@ -45,6 +45,7 @@ class AuthorizePacket(injector: HasAndroidInjector) : MedtrumPacket(injector) { ).toInt() if (medtrumPump.deviceType != deviceType) { + aapsLogger.warn(LTag.PUMPCOMM, "GetDeviceTypeState: deviceType changed from ${medtrumPump.deviceType} to $deviceType") medtrumPump.deviceType = deviceType } if (medtrumPump.swVersion != swVersion) { 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 75b36b0097..4d4d0a8d95 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 @@ -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.MedtrumPumpState import info.nightscout.pump.medtrum.comm.packets.* +import info.nightscout.pump.medtrum.util.MedtrumSnUtil import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventAppExit @@ -109,8 +110,9 @@ class MedtrumService : DaggerService(), BLECommCallback { .subscribe({ event -> if (event.isChanged(rh.gs(R.string.key_sn_input))) { aapsLogger.debug(LTag.PUMPCOMM, "Serial number changed, reporting new pump!") - pumpSync.connectNewPump() medtrumPump.loadUserSettingsFromSP() + medtrumPump.deviceType = MedtrumSnUtil().getDeviceTypeFromSerial(medtrumPump.pumpSN) + pumpSync.connectNewPump() medtrumPump.setFakeTBRIfNeeded() } 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)) } - MedtrumPumpState.DAILY_MAX_SUSPENDED -> { + MedtrumPumpState.DAILY_MAX_SUSPENDED -> { result = sendPacketAndGetResponse(ClearPumpAlarmPacket(injector, ALARM_DAILY_MAX_CLEAR_CODE)) } - else -> { + else -> { // Nothing to reset } } @@ -488,23 +490,23 @@ class MedtrumService : DaggerService(), BLECommCallback { private fun handlePumpStateUpdate(state: MedtrumPumpState) { // Map the pump state to an alarm state and add it to the active alarms val alarmState = when (state) { - MedtrumPumpState.NONE -> AlarmState.NONE - MedtrumPumpState.LOW_BG_SUSPENDED -> AlarmState.LOW_BG_SUSPENDED - MedtrumPumpState.LOW_BG_SUSPENDED2 -> AlarmState.LOW_BG_SUSPENDED2 + MedtrumPumpState.NONE -> AlarmState.NONE + MedtrumPumpState.LOW_BG_SUSPENDED -> AlarmState.LOW_BG_SUSPENDED + MedtrumPumpState.LOW_BG_SUSPENDED2 -> AlarmState.LOW_BG_SUSPENDED2 MedtrumPumpState.AUTO_SUSPENDED -> AlarmState.AUTO_SUSPENDED MedtrumPumpState.HOURLY_MAX_SUSPENDED -> AlarmState.HOURLY_MAX_SUSPENDED MedtrumPumpState.DAILY_MAX_SUSPENDED -> AlarmState.DAILY_MAX_SUSPENDED MedtrumPumpState.SUSPENDED -> AlarmState.SUSPENDED - MedtrumPumpState.PAUSED -> AlarmState.PAUSED - MedtrumPumpState.OCCLUSION -> AlarmState.OCCLUSION - MedtrumPumpState.EXPIRED -> AlarmState.EXPIRED - MedtrumPumpState.RESERVOIR_EMPTY -> AlarmState.RESERVOIR_EMPTY - MedtrumPumpState.PATCH_FAULT -> AlarmState.PATCH_FAULT - MedtrumPumpState.PATCH_FAULT2 -> AlarmState.PATCH_FAULT2 - MedtrumPumpState.BASE_FAULT -> AlarmState.BASE_FAULT - MedtrumPumpState.BATTERY_OUT -> AlarmState.BATTERY_OUT - MedtrumPumpState.NO_CALIBRATION -> AlarmState.NO_CALIBRATION - else -> null + MedtrumPumpState.PAUSED -> AlarmState.PAUSED + MedtrumPumpState.OCCLUSION -> AlarmState.OCCLUSION + MedtrumPumpState.EXPIRED -> AlarmState.EXPIRED + MedtrumPumpState.RESERVOIR_EMPTY -> AlarmState.RESERVOIR_EMPTY + MedtrumPumpState.PATCH_FAULT -> AlarmState.PATCH_FAULT + MedtrumPumpState.PATCH_FAULT2 -> AlarmState.PATCH_FAULT2 + MedtrumPumpState.BASE_FAULT -> AlarmState.BASE_FAULT + MedtrumPumpState.BATTERY_OUT -> AlarmState.BATTERY_OUT + MedtrumPumpState.NO_CALIBRATION -> AlarmState.NO_CALIBRATION + else -> null } if (alarmState != null && alarmState != AlarmState.NONE) { medtrumPump.addAlarm(alarmState) @@ -519,7 +521,7 @@ class MedtrumService : DaggerService(), BLECommCallback { // Map the pump state to a notification when (state) { MedtrumPumpState.NONE, - MedtrumPumpState.STOPPED -> { + MedtrumPumpState.STOPPED -> { rxBus.send(EventDismissNotification(Notification.PUMP_ERROR)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) uiInteraction.addNotification( @@ -536,7 +538,7 @@ class MedtrumService : DaggerService(), BLECommCallback { MedtrumPumpState.PRIMING, MedtrumPumpState.PRIMED, MedtrumPumpState.EJECTING, - MedtrumPumpState.EJECTED -> { + MedtrumPumpState.EJECTED -> { rxBus.send(EventDismissNotification(Notification.PUMP_ERROR)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) medtrumPump.setFakeTBRIfNeeded() @@ -544,7 +546,7 @@ class MedtrumService : DaggerService(), BLECommCallback { } MedtrumPumpState.ACTIVE, - MedtrumPumpState.ACTIVE_ALT -> { + MedtrumPumpState.ACTIVE_ALT -> { rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) medtrumPump.clearAlarmState() @@ -554,7 +556,7 @@ class MedtrumService : DaggerService(), BLECommCallback { MedtrumPumpState.LOW_BG_SUSPENDED2, MedtrumPumpState.AUTO_SUSPENDED, MedtrumPumpState.SUSPENDED, - MedtrumPumpState.PAUSED -> { + MedtrumPumpState.PAUSED -> { uiInteraction.addNotification( Notification.PUMP_SUSPENDED, rh.gs(R.string.pump_is_suspended), @@ -572,7 +574,7 @@ class MedtrumService : DaggerService(), BLECommCallback { // Pump will report proper TBR for this } - MedtrumPumpState.DAILY_MAX_SUSPENDED -> { + MedtrumPumpState.DAILY_MAX_SUSPENDED -> { uiInteraction.addNotification( Notification.PUMP_SUSPENDED, rh.gs(R.string.pump_is_suspended_day_max), @@ -588,7 +590,7 @@ class MedtrumService : DaggerService(), BLECommCallback { MedtrumPumpState.PATCH_FAULT2, MedtrumPumpState.BASE_FAULT, MedtrumPumpState.BATTERY_OUT, - MedtrumPumpState.NO_CALIBRATION -> { + MedtrumPumpState.NO_CALIBRATION -> { rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) // Pump suspended due to error, show error! @@ -752,21 +754,7 @@ class MedtrumService : DaggerService(), BLECommCallback { // Success! responseHandled = true responseSuccess = true - // Check if we have a supported pump - 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()) - } + toState(GetDeviceTypeState()) } else if (mPacket?.failed == true) { // Failure responseHandled = true diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/util/MedtrumSnUtil.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/util/MedtrumSnUtil.kt new file mode 100644 index 0000000000..ad16adc630 --- /dev/null +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/util/MedtrumSnUtil.kt @@ -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 + } + } +} diff --git a/pump/medtrum/src/main/res/values/strings.xml b/pump/medtrum/src/main/res/values/strings.xml index 361b32dbdd..9bb6314cf5 100644 --- a/pump/medtrum/src/main/res/values/strings.xml +++ b/pump/medtrum/src/main/res/values/strings.xml @@ -28,7 +28,6 @@ Pump integration for Medtrum Nano Medtrum pump settings Pump error: %1$s !! - Pump untested: %1$d! Please contact us at discord or github for support Pump is suspended Pump is suspended due to hourly max insulin exceeded Pump is suspended due to daily max insulin exceeded @@ -131,6 +130,8 @@ Serial Number Enter the serial number of your pump base. + Invalid serial number! Check serial number and try again. + Pump untested: %1$d! Please contact us at discord or github for support Alarm Settings Select your preferred pump alarm settings. Patch Expiration