display bluetooth connection status. display deliveryStatus. display lastConnection

This commit is contained in:
Andrei Vereha 2021-05-30 22:49:35 +02:00
parent 3b26068faf
commit 91957930ed
9 changed files with 109 additions and 83 deletions

View file

@ -407,8 +407,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
else -> else ->
throw IllegalArgumentException( aapsLogger.warn(LTag.PUMP,
"Don't know how to sync confirmed command of type: $historyEntry and " + "Will not sync confirmed command of type: $historyEntry and " +
"succes: ${confirmation.success}" "succes: ${confirmation.success}"
) )
} }

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.ConnectionState
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
@ -11,7 +11,7 @@ interface OmnipodDashBleManager {
fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent>
fun getStatus(): ConnectionStatus fun getStatus(): ConnectionState
fun connect(): Observable<PodEvent> fun connect(): Observable<PodEvent>

View file

@ -11,7 +11,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptio
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
@ -34,7 +33,6 @@ class OmnipodDashBleManagerImpl @Inject constructor(
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
private var connection: Connection? = null private var connection: Connection? = null
private var status: ConnectionStatus = ConnectionStatus.IDLE
private val ids = Ids(podState) private val ids = Ids(podState)
override fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> = override fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> =
@ -85,13 +83,9 @@ class OmnipodDashBleManagerImpl @Inject constructor(
?: throw NotConnectedException("Missing session") ?: throw NotConnectedException("Missing session")
} }
override fun getStatus(): ConnectionStatus { override fun getStatus(): ConnectionState {
// TODO is this used? return connection?.let{ getStatus() }
var s: ConnectionStatus ?: NotConnected
synchronized(status) {
s = status
}
return s
} }
override fun connect(): Observable<PodEvent> = Observable.create { emitter -> override fun connect(): Observable<PodEvent> = Observable.create { emitter ->
@ -106,9 +100,10 @@ class OmnipodDashBleManagerImpl @Inject constructor(
?: throw FailedToConnectException("Missing bluetoothAddress, activate the pod first") ?: throw FailedToConnectException("Missing bluetoothAddress, activate the pod first")
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
val conn = connection val conn = connection
?: Connection(podDevice, aapsLogger, context) ?: Connection(podDevice, aapsLogger, context, podState)
connection = conn connection = conn
if (conn.connectionState() is Connected) { if (conn.connectionState() is Connected) {
podState.lastConnection = System.currentTimeMillis()
if (conn.session == null) { if (conn.session == null) {
emitter.onNext(PodEvent.EstablishingSession) emitter.onNext(PodEvent.EstablishingSession)
establishSession(1.toByte()) establishSession(1.toByte())
@ -121,7 +116,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
} }
conn.connect() conn.connect()
emitter.onNext(PodEvent.BluetoothConnected(podAddress)) emitter.onNext(PodEvent.BluetoothConnected(podAddress))
podState.lastConnection = System.currentTimeMillis()
emitter.onNext(PodEvent.EstablishingSession) emitter.onNext(PodEvent.EstablishingSession)
establishSession(1.toByte()) establishSession(1.toByte())
emitter.onNext(PodEvent.Connected) emitter.onNext(PodEvent.Connected)
@ -190,7 +185,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
emitter.onNext(PodEvent.BluetoothConnecting) emitter.onNext(PodEvent.BluetoothConnecting)
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
val conn = Connection(podDevice, aapsLogger, context) val conn = Connection(podDevice, aapsLogger, context, podState)
connection = conn connection = conn
emitter.onNext(PodEvent.BluetoothConnected(podAddress)) emitter.onNext(PodEvent.BluetoothConnected(podAddress))

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CmdBl
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.DataBleIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.DataBleIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.IncomingPackets import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.IncomingPackets
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
sealed class ConnectionState sealed class ConnectionState
@ -29,7 +30,8 @@ object NotConnected : ConnectionState()
class Connection( class Connection(
private val podDevice: BluetoothDevice, private val podDevice: BluetoothDevice,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
context: Context context: Context,
private val podState: OmnipodDashPodStateManager
) : DisconnectHandler { ) : DisconnectHandler {
private val incomingPackets = IncomingPackets() private val incomingPackets = IncomingPackets()
@ -50,13 +52,15 @@ class Connection(
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}") aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}")
val autoConnect = false val autoConnect = false
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE) gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
// OnDisconnect can be called after this point!!! // OnDisconnect can be called after this point!!!
val state = waitForConnection() val state = waitForConnection()
if (state !is Connected) { if (state !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
throw FailedToConnectException(podDevice.address) throw FailedToConnectException(podDevice.address)
} }
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
val discoveredCharacteristics = discoverer.discoverServices() val discoveredCharacteristics = discoverer.discoverServices()
cmdBleIO = CmdBleIO( cmdBleIO = CmdBleIO(
@ -90,13 +94,18 @@ class Connection(
disconnect() disconnect()
} }
aapsLogger.debug("Connecting") aapsLogger.debug("Connecting")
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
if (!gattConnection.connect()) { if (!gattConnection.connect()) {
throw FailedToConnectException("connect() returned false") throw FailedToConnectException("connect() returned false")
} }
if (waitForConnection() is NotConnected) { if (waitForConnection() !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
throw FailedToConnectException(podDevice.address) throw FailedToConnectException(podDevice.address)
} }
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
val discovered = discoverer.discoverServices() val discovered = discoverer.discoverServices()
@ -110,6 +119,8 @@ class Connection(
fun disconnect() { fun disconnect() {
aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting") aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting")
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
gattConnection.disconnect() gattConnection.disconnect()
bleCommCallbacks.resetConnection() bleCommCallbacks.resetConnection()
session = null session = null

View file

@ -1,10 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status
enum class ConnectionStatus {
IDLE,
BUSY,
CONNECTING,
ESTABLISHING_SESSION,
PAIRING,
RUNNING_COMMAND;
}

View file

@ -22,6 +22,7 @@ interface OmnipodDashPodStateManager {
val isSuspended: Boolean val isSuspended: Boolean
val isPodRunning: Boolean val isPodRunning: Boolean
var lastConnection: Long var lastConnection: Long
var bluetoothConnectionState: BluetoothConnectionState
val lastUpdatedSystem: Long // System.currentTimeMillis() val lastUpdatedSystem: Long // System.currentTimeMillis()
val lastStatusResponseReceived: Long val lastStatusResponseReceived: Long
@ -79,4 +80,8 @@ interface OmnipodDashPodStateManager {
) )
// TODO: set created to "now" on boot // TODO: set created to "now" on boot
data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable
enum class BluetoothConnectionState {
CONNECTING, CONNECTED, DISCONNECTED
}
} }

View file

@ -160,6 +160,14 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val lastStatusResponseReceived: Long override val lastStatusResponseReceived: Long
get() = podState.lastStatusResponseReceived get() = podState.lastStatusResponseReceived
override var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState
get() = podState.bluetoothConnectionState
set(bluetoothConnectionState) {
podState.bluetoothConnectionState = bluetoothConnectionState
rxBus.send(EventOmnipodDashPumpValuesChanged())
// do not store
}
override fun increaseMessageSequenceNumber() { override fun increaseMessageSequenceNumber() {
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort() podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
store() store()
@ -380,7 +388,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
var lastConnection: Long = 0 var lastConnection: Long = 0
var lastUpdatedSystem: Long = 0 var lastUpdatedSystem: Long = 0
var lastStatusResponseReceived: Long = 0 var lastStatusResponseReceived: Long = 0
var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState =
OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
var messageSequenceNumber: Short = 0 var messageSequenceNumber: Short = 0
var sequenceNumberOfLastProgrammingCommand: Short? = null var sequenceNumberOfLastProgrammingCommand: Short? = null
var activationTime: Long? = null var activationTime: Long? = null

View file

@ -13,6 +13,7 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
@ -41,6 +42,7 @@ import info.nightscout.androidaps.utils.ui.UIRunnable
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import org.joda.time.DateTime
import org.joda.time.Duration import org.joda.time.Duration
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -58,6 +60,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var pumpSync: PumpSync
companion object { companion object {
@ -211,11 +215,26 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
private fun updateUi() { private fun updateUi() {
// TODO update bluetooth status // TODO update bluetooth status
updateBluetoothStatus()
updateOmnipodStatus() updateOmnipodStatus()
updatePodActionButtons() updatePodActionButtons()
updateQueueStatus() updateQueueStatus()
} }
private fun updateBluetoothStatus(){
bluetoothStatusBinding.omnipodDashBluetoothAddress.text = podStateManager.bluetoothAddress
?: PLACEHOLDER
bluetoothStatusBinding.omnipodDashBluetoothStatus.text =
when (podStateManager.bluetoothConnectionState) {
OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED ->
"{fa-bluetooth}"
OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED ->
"{fa-bluetooth-b}"
OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING ->
"{fa-bluetooth-b spin}"
}
}
private fun updateOmnipodStatus() { private fun updateOmnipodStatus() {
updateLastConnection() updateLastConnection()
updateLastBolus() updateLastBolus()
@ -246,10 +265,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
podStateManager.firmwareVersion.toString(), podStateManager.firmwareVersion.toString(),
podStateManager.bluetoothVersion.toString() podStateManager.bluetoothVersion.toString()
) )
podInfoBinding.timeOnPod.text = podStateManager.minutesSinceActivation.toString() + " minutes"
// TODO // TODO
/* /*
podInfoBinding.timeOnPod.text = readableZonedTime(podStateManager.time)
podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) { podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) {
Color.RED Color.RED
} else { } else {
@ -373,7 +391,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
if (podStateManager.isSuspended) { if (podStateManager.isSuspended) {
resourceHelper.gs(R.string.omnipod_common_pod_status_suspended) resourceHelper.gs(R.string.omnipod_common_pod_status_suspended)
} else { } else {
resourceHelper.gs(R.string.omnipod_common_pod_status_running) resourceHelper.gs(R.string.omnipod_common_pod_status_running) +
podStateManager.deliveryStatus?.let{ " " + podStateManager.deliveryStatus.toString() }
} }
// TODO // TODO
/* /*
@ -421,10 +440,11 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
} }
private fun updateTempBasal() { private fun updateTempBasal() {
if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive) { val tempBasal = podStateManager.tempBasal
val startTime = podStateManager.tempBasal!!.startTime if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive && tempBasal != null) {
val rate = podStateManager.tempBasal!!.rate val startTime = tempBasal.startTime
val duration = podStateManager.tempBasal!!.durationInMinutes val rate = tempBasal.rate
val duration = tempBasal.durationInMinutes
val minutesRunning = 0 // TODO val minutesRunning = 0 // TODO
@ -560,12 +580,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
} }
*/ */
private fun readableDuration(time: Long): String { private fun readableDuration(dateTime: Long): String {
// TODO val duration = Duration(dateTime, System.currentTimeMillis())
return "TODO"
/*
val duration = Duration(dateTime, DateTime.now())
val hours = duration.standardHours.toInt() val hours = duration.standardHours.toInt()
val minutes = duration.standardMinutes.toInt() val minutes = duration.standardMinutes.toInt()
val seconds = duration.standardSeconds.toInt() val seconds = duration.standardSeconds.toInt()
@ -599,7 +615,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days)) return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days))
} }
} }
*/
} }
private fun isQueueEmpty(): Boolean { private fun isQueueEmpty(): Boolean {

View file

@ -1,44 +1,6 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/omnipod_dash_overview_bluetooth_address"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/omnipod_dash_bluetooth_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -65,7 +27,8 @@
android:textSize="14sp" android:textSize="14sp"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<com.joanzapata.iconify.widget.IconTextView
<TextView
android:id="@+id/omnipod_dash_bluetooth_address" android:id="@+id/omnipod_dash_bluetooth_address"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -73,6 +36,43 @@
android:gravity="start" android:gravity="start"
android:paddingStart="5dp" android:paddingStart="5dp"
android:paddingEnd="5dp" android:paddingEnd="5dp"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/omnipod_dash_overview_bluetooth_address"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/omnipod_dash_bluetooth_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="{fa-bluetooth-b} " android:text="{fa-bluetooth-b} "
android:textSize="14sp" android:textSize="14sp"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />