mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-29 04:14:31 +01:00
Fix CGM profile
This commit is contained in:
@@ -37,6 +37,7 @@ import android.util.Log
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
val String.Companion.EMPTY
|
||||
@@ -53,6 +54,6 @@ private val exceptionHandler = CoroutineExceptionHandler { _, t ->
|
||||
}
|
||||
|
||||
fun CoroutineScope.launchWithCatch(block: suspend CoroutineScope.() -> Unit) =
|
||||
launch(Job() + exceptionHandler) {
|
||||
launch(SupervisorJob() + exceptionHandler) {
|
||||
block()
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ internal data class CGMServiceData(
|
||||
val records: List<CGMRecordWithSequenceNumber> = emptyList(),
|
||||
val batteryLevel: Int? = null,
|
||||
val connectionState: GattConnectionState? = null,
|
||||
val requestStatus: RequestStatus = RequestStatus.IDLE
|
||||
val requestStatus: RequestStatus = RequestStatus.IDLE,
|
||||
val deviceName: String? = null
|
||||
)
|
||||
|
||||
data class CGMRecordWithSequenceNumber(
|
||||
|
||||
@@ -69,6 +69,7 @@ class CGMRepository @Inject constructor(
|
||||
val highestSequenceNumber = data.value.records.maxOfOrNull { it.sequenceNumber } ?: -1
|
||||
|
||||
fun launch(device: ServerDevice) {
|
||||
_data.value = _data.value.copy(deviceName = device.name)
|
||||
serviceManager.startService(CGMService::class.java, device)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ import no.nordicsemi.android.kotlin.ble.profile.racp.RACPOpCode
|
||||
import no.nordicsemi.android.kotlin.ble.profile.racp.RACPResponseCode
|
||||
import no.nordicsemi.android.service.DEVICE_DATA
|
||||
import no.nordicsemi.android.service.NotificationService
|
||||
import no.nordicsemi.android.utils.launchWithCatch
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -139,12 +140,12 @@ internal class CGMService : NotificationService() {
|
||||
}
|
||||
|
||||
private suspend fun configureGatt(services: BleGattServices) {
|
||||
val glsService = services.findService(CGMS_SERVICE_UUID)!!
|
||||
val statusCharacteristic = glsService.findCharacteristic(CGM_STATUS_UUID)!!
|
||||
val featureCharacteristic = glsService.findCharacteristic(CGM_FEATURE_UUID)!!
|
||||
val measurementCharacteristic = glsService.findCharacteristic(CGM_MEASUREMENT_UUID)!!
|
||||
val opsControlPointCharacteristic = glsService.findCharacteristic(CGM_OPS_CONTROL_POINT_UUID)!!
|
||||
recordAccessControlPointCharacteristic = glsService.findCharacteristic(RACP_UUID)!!
|
||||
val cgmService = services.findService(CGMS_SERVICE_UUID)!!
|
||||
val statusCharacteristic = cgmService.findCharacteristic(CGM_STATUS_UUID)!!
|
||||
val featureCharacteristic = cgmService.findCharacteristic(CGM_FEATURE_UUID)!!
|
||||
val measurementCharacteristic = cgmService.findCharacteristic(CGM_MEASUREMENT_UUID)!!
|
||||
val opsControlPointCharacteristic = cgmService.findCharacteristic(CGM_OPS_CONTROL_POINT_UUID)!!
|
||||
recordAccessControlPointCharacteristic = cgmService.findCharacteristic(RACP_UUID)!!
|
||||
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
|
||||
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
|
||||
|
||||
@@ -194,12 +195,16 @@ internal class CGMService : NotificationService() {
|
||||
.onEach { onAccessControlPointDataReceived(it) }
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
val featuresEnvelope = featureCharacteristic.read().let { CGMFeatureParser.parse(it) }!!
|
||||
secured = featuresEnvelope.features.e2eCrcSupported
|
||||
lifecycleScope.launchWithCatch {
|
||||
val featuresEnvelope = featureCharacteristic.read().let { CGMFeatureParser.parse(it) }!!
|
||||
secured = featuresEnvelope.features.e2eCrcSupported
|
||||
}
|
||||
|
||||
val statusEnvelope = statusCharacteristic.read().let { CGMStatusParser.parse(it) }!!
|
||||
if (!statusEnvelope.status.sessionStopped) {
|
||||
sessionStartTime = System.currentTimeMillis() - statusEnvelope.timeOffset * 60000L
|
||||
lifecycleScope.launchWithCatch {
|
||||
val statusEnvelope = statusCharacteristic.read().let { CGMStatusParser.parse(it) }!!
|
||||
if (!statusEnvelope.status.sessionStopped) {
|
||||
sessionStartTime = System.currentTimeMillis() - statusEnvelope.timeOffset * 60000L
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionStartTime == 0L) {
|
||||
|
||||
@@ -44,6 +44,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import no.nordicsemi.android.cgms.R
|
||||
import no.nordicsemi.android.cgms.data.CGMServiceData
|
||||
import no.nordicsemi.android.cgms.viewmodel.CGMViewModel
|
||||
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
|
||||
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
|
||||
@@ -73,12 +74,12 @@ fun CGMScreen() {
|
||||
if (state.deviceName == null) {
|
||||
DeviceConnectingView()
|
||||
} else {
|
||||
when (state.result?.connectionState) {
|
||||
when (state.connectionState) {
|
||||
null,
|
||||
GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) }
|
||||
GattConnectionState.STATE_DISCONNECTED,
|
||||
GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(Reason.UNKNOWN) { NavigateUpButton(navigateUp) }
|
||||
GattConnectionState.STATE_CONNECTED -> CGMContentView(state.result) { viewModel.onEvent(it) }
|
||||
GattConnectionState.STATE_CONNECTED -> CGMContentView(state) { viewModel.onEvent(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +87,7 @@ fun CGMScreen() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppBar(state: CGMViewState, navigateUp: () -> Unit, viewModel: CGMViewModel) {
|
||||
private fun AppBar(state: CGMServiceData, navigateUp: () -> Unit, viewModel: CGMViewModel) {
|
||||
if (state.deviceName?.isNotBlank() == true) {
|
||||
LoggerIconAppBar(state.deviceName, navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
|
||||
viewModel.onEvent(OpenLoggerEvent)
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.cgms.view
|
||||
|
||||
import no.nordicsemi.android.cgms.data.CGMServiceData
|
||||
|
||||
internal data class CGMViewState(
|
||||
val result: CGMServiceData? = null,
|
||||
val deviceName: String? = null
|
||||
)
|
||||
@@ -48,7 +48,6 @@ import no.nordicsemi.android.cgms.data.CGMServiceCommand
|
||||
import no.nordicsemi.android.cgms.repository.CGMRepository
|
||||
import no.nordicsemi.android.cgms.repository.CGMS_SERVICE_UUID
|
||||
import no.nordicsemi.android.cgms.view.CGMViewEvent
|
||||
import no.nordicsemi.android.cgms.view.CGMViewState
|
||||
import no.nordicsemi.android.cgms.view.DisconnectEvent
|
||||
import no.nordicsemi.android.cgms.view.NavigateUp
|
||||
import no.nordicsemi.android.cgms.view.OnWorkingModeSelected
|
||||
@@ -67,8 +66,7 @@ internal class CGMViewModel @Inject constructor(
|
||||
private val analytics: AppAnalytics
|
||||
) : ViewModel() {
|
||||
|
||||
private val _state = MutableStateFlow(CGMViewState())
|
||||
val state = _state.asStateFlow()
|
||||
val state = repository.data
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
@@ -78,8 +76,6 @@ internal class CGMViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
repository.data.onEach {
|
||||
_state.value = _state.value.copy(result = it)
|
||||
|
||||
if (it.connectionState == GattConnectionState.STATE_CONNECTED) {
|
||||
analytics.logEvent(ProfileConnectedEvent(Profile.CGMS))
|
||||
}
|
||||
@@ -106,10 +102,14 @@ internal class CGMViewModel @Inject constructor(
|
||||
private fun handleResult(result: NavigationResult<ServerDevice>) {
|
||||
when (result) {
|
||||
is NavigationResult.Cancelled -> navigationManager.navigateUp()
|
||||
is NavigationResult.Success -> repository.launch(result.value)
|
||||
is NavigationResult.Success -> onDeviceSelected(result.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDeviceSelected(device: ServerDevice) {
|
||||
repository.launch(device)
|
||||
}
|
||||
|
||||
private fun onCommandReceived(workingMode: CGMServiceCommand) {
|
||||
repository.onCommand(workingMode)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user