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 a365e8e3bd..bcc4d77733 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 @@ -261,7 +261,7 @@ class MedtrumPump @Inject constructor( aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: basal: $basal") break } - aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: rate: $rate, startMinutes: $startMinutes, endMinutes: $endMinutes") + // aapsLogger.debug(LTag.PUMP, "getCurrentHourlyBasalFromMedtrumProfileArray: rate: $rate, startMinutes: $startMinutes, endMinutes: $endMinutes") } return basal } @@ -275,8 +275,9 @@ class MedtrumPump @Inject constructor( LTag.PUMP, "handleBasalStatusUpdate: basalType: $basalType basalValue: $basalRate basalSequence: $basalSequence basalPatchId: $basalPatchId basalStartTime: $basalStartTime " + "receivedTime: $receivedTime" ) - if (basalType.isTempBasal()) { - // TODO: Is this the correct place to sync temporaryBasalInfo? Note: it will be removed after getting it once, So this would only apply when called in setTempBasalPacket, maybe first check if basal entry already exists and leave this here, then we can also let the onNotification stuff sync basal? + val expectedTemporaryBasal = pumpSync.expectedPumpState().temporaryBasal + if (basalType.isTempBasal() && expectedTemporaryBasal?.pumpId != basalStartTime) { + // Note: temporaryBasalInfo will be removed from temporaryBasalStorage after this call val temporaryBasalInfo = temporaryBasalStorage.findTemporaryBasal(basalStartTime, basalRate) // If duration is unknown, no way to get it now, set patch lifetime as duration @@ -293,9 +294,9 @@ class MedtrumPump @Inject constructor( ) aapsLogger.debug( LTag.PUMPCOMM, - "handleBasalStatusUpdate: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + "Rate: $basalRate Duration: ${duration}min" + "handleBasalStatusUpdate: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_START ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + "Rate: $basalRate Duration: ${duration}" ) - } else if (basalType.isSuspendedByPump()) { + } else if (basalType.isSuspendedByPump() && expectedTemporaryBasal?.pumpId != basalStartTime) { val newRecord = pumpSync.syncTemporaryBasalWithPumpId( timestamp = basalStartTime, rate = 0.0, 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 4cf10a580c..5125de09fa 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 @@ -2,10 +2,12 @@ package info.nightscout.pump.medtrum.comm.packets import dagger.android.HasAndroidInjector import info.nightscout.pump.medtrum.MedtrumPump +import info.nightscout.pump.medtrum.comm.enums.CommandType import info.nightscout.pump.medtrum.comm.enums.CommandType.AUTH_REQ import info.nightscout.pump.medtrum.encryption.Crypt import info.nightscout.pump.medtrum.extension.toByteArray import info.nightscout.pump.medtrum.extension.toInt +import info.nightscout.rx.logging.LTag import javax.inject.Inject class AuthorizePacket(injector: HasAndroidInjector) : MedtrumPacket(injector) { @@ -39,6 +41,14 @@ class AuthorizePacket(injector: HasAndroidInjector) : MedtrumPacket(injector) { } override fun handleResponse(data: ByteArray): Boolean { + if (data.size > 3) { + val incomingOpCode: Byte = data.copyOfRange(RESP_OPCODE_START, RESP_OPCODE_END).first() + if (incomingOpCode == CommandType.SUBSCRIBE.code) { + // TODO: Test and see if this can be removed + aapsLogger.error(LTag.PUMPCOMM, "handleResponse: Got subscribe response instead of authorize response, handling subscribe packet") + return SubscribePacket(injector).handleResponse(data) + } + } val success = super.handleResponse(data) if (success) { deviceType = data.copyOfRange(RESP_DEVICE_TYPE_START, RESP_DEVICE_TYPE_END).toInt() diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt index d817895fa5..0f45e405b8 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/GetRecordPacket.kt @@ -125,7 +125,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int aapsLogger.debug( LTag.PUMPCOMM, "handleBasalStatusUpdate from record: ${if (newRecord) "**NEW** " else ""}EVENT TEMP_SYNC: ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + - "Rate: $basalRate Duration: ${duration}min" + "Rate: $basalRate Duration: ${duration}" ) } else { // Sync only end ? pumpSync.syncStopTemporaryBasalWithPumpId( @@ -136,7 +136,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int ) aapsLogger.warn( LTag.PUMPCOMM, - "handleBasalStatusUpdate from record: EVENT TEMP_END ($basalType) ${dateUtil.dateAndTimeString(basalEndTime)} ($basalEndTime) " + "Rate: $basalRate Duration: ${duration}min" + "handleBasalStatusUpdate from record: EVENT TEMP_END ($basalType) ${dateUtil.dateAndTimeString(basalEndTime)} ($basalEndTime) " + "Rate: $basalRate Duration: ${duration}" ) } } @@ -156,7 +156,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int aapsLogger.debug( LTag.PUMPCOMM, "handleBasalStatusUpdate from record: ${if (newRecord) "**NEW** " else ""}EVENT SUSPEND: ($basalType) ${dateUtil.dateAndTimeString(basalStartTime)} ($basalStartTime) " + - "Rate: $basalRate Duration: ${duration}min" + "Rate: $basalRate Duration: ${duration}" ) } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/MedtrumPacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/MedtrumPacket.kt index 6386e988ef..6b175c06df 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/MedtrumPacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/MedtrumPacket.kt @@ -16,10 +16,10 @@ open class MedtrumPacket(protected var injector: HasAndroidInjector) { companion object { - private const val RESP_OPCODE_START = 1 - private const val RESP_OPCODE_END = RESP_OPCODE_START + 1 - private const val RESP_RESULT_START = 4 - private const val RESP_RESULT_END = RESP_RESULT_START + 2 + const val RESP_OPCODE_START = 1 + const val RESP_OPCODE_END = RESP_OPCODE_START + 1 + const val RESP_RESULT_START = 4 + const val RESP_RESULT_END = RESP_RESULT_START + 2 private const val RESP_WAITING = 16384 } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt index 37f9ec0465..ef03a67f71 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/comm/packets/NotificationPacket.kt @@ -127,9 +127,7 @@ class NotificationPacket(val injector: HasAndroidInjector) { LTag.PUMPCOMM, "Basal type: $basalType, basal sequence: $basalSequence, basal patch id: $basalPatchId, basal time: $basalTime, basal rate: $basalRate, basal delivery: $basalDelivery" ) - // TODO: Check if basal is known, if not add it - // medtrumPump.handleBasalStatusUpdate(basalType, basalRate, basalSequence, basalPatchId, basalTime) - // TODO: Handle basal delivery + medtrumPump.handleBasalStatusUpdate(basalType, basalRate, basalSequence, basalPatchId, basalTime) offset += 12 } diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt index 0f958790c8..12c23b15db 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt @@ -92,7 +92,6 @@ class BLEComm @Inject internal constructor( var isConnected = false // TODO: These may be removed have no function var isConnecting = false// TODO: These may be removed have no function - private var retryCounter = 0 private var uartWrite: BluetoothGattCharacteristic? = null private var uartRead: BluetoothGattCharacteristic? = null @@ -102,6 +101,7 @@ class BLEComm @Inject internal constructor( private var mDeviceSN: Long = 0 private var mCallback: BLECommCallback? = null + private var mDevice: BluetoothDevice? = null fun setCallback(callback: BLECommCallback?) { this.mCallback = callback @@ -144,6 +144,7 @@ class BLEComm @Inject internal constructor( mBluetoothAdapter?.bluetoothLeScanner?.stopScan(mScanCallback) } + @Synchronized fun connect(from: String, deviceSN: Long): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED @@ -157,10 +158,20 @@ class BLEComm @Inject internal constructor( aapsLogger.error("Unable to obtain a BluetoothAdapter.") return false } - mDeviceSN = deviceSN - isConnecting = true - retryCounter = 0 - startScan() + + if (mDevice != null && mDeviceSN == deviceSN) { + // Skip scanning and directly connect to gatt + aapsLogger.debug(LTag.PUMPBTCOMM, "Skipping scan and directly connecting to gatt") + isConnecting = true + connectGatt(mDevice!!) + } else { + // Scan for device + aapsLogger.debug(LTag.PUMPBTCOMM, "Scanning for device") + mDeviceSN = deviceSN + isConnecting = true + startScan() + } + return true } @@ -215,6 +226,7 @@ class BLEComm @Inject internal constructor( if (manufacturerData?.getDeviceSN() == mDeviceSN) { aapsLogger.debug(LTag.PUMPBTCOMM, "Found our device! deviceSN: " + manufacturerData.getDeviceSN()) stopScan() + mDevice = result.device connectGatt(result.device) } } @@ -376,20 +388,11 @@ class BLEComm @Inject internal constructor( mBluetoothGatt?.discoverServices() }, WRITE_DELAY_MILLIS) } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - if (status == 133 && isConnecting && retryCounter < 3) { - // Special case for status 133 when we are connecting - // We need to close gatt and try to reconnect - aapsLogger.debug(LTag.PUMPBTCOMM, "onConnectionStateChange status 133") - close() - startScan() - retryCounter++ - } else { - close() - isConnected = false - isConnecting = false - mCallback?.onBLEDisconnected() - aapsLogger.debug(LTag.PUMPBTCOMM, "Device was disconnected " + gatt.device.name) //Device was disconnectedS - } + close() + isConnected = false + isConnecting = false + mCallback?.onBLEDisconnected() + aapsLogger.debug(LTag.PUMPBTCOMM, "Device was disconnected " + gatt.device.name) //Device was disconnected } } 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 19459453fc..23533c744f 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 @@ -329,6 +329,7 @@ class MedtrumService : DaggerService(), BLECommCallback { // State for connect flow, could be replaced by commandState and steps in connect() private inner class AuthState : State() { + val retryCounter = 0 override fun onEnter() { aapsLogger.debug(LTag.PUMPCOMM, "Medtrum Service reached AuthState") @@ -346,8 +347,15 @@ class MedtrumService : DaggerService(), BLECommCallback { toState(GetDeviceTypeState()) } else if (mPacket?.failed == true) { // Failure - bleComm.disconnect("Failure") - toState(IdleState()) + // retry twice + // TODO: Test and see if this can be removed + if (retryCounter < 2) { + aapsLogger.error(LTag.PUMPCOMM, "AuthState failed!, retrying") + mPacket?.getRequest()?.let { bleComm.sendMessage(it) } + } else { + bleComm.disconnect("Failure") + toState(IdleState()) + } } } }