Add alarm to PRX

This commit is contained in:
Sylwester Zielinski
2023-03-22 10:56:50 +01:00
parent a5306eaf71
commit 4f0cdc08c9
5 changed files with 38 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
package no.nordicsemi.android.prx.data
import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel
@@ -8,6 +9,12 @@ data class PRXServiceData(
val linkLossAlarmLevel: AlarmLevel = AlarmLevel.HIGH,
val batteryLevel: Int? = null,
val connectionState: GattConnectionState? = null,
val connectionStatus: BleGattConnectionStatus? = null,
val isRemoteAlarm: Boolean = false,
val deviceName: String? = null
)
) {
val isLinkLossDisconnected = connectionState?.let {
connectionStatus == BleGattConnectionStatus.LINK_LOSS
} ?: false
}

View File

@@ -60,6 +60,10 @@ internal class AlarmHandler @Inject constructor(
}
fun playAlarm(alarmLevel: AlarmLevel) {
if (alarmLevel == AlarmLevel.NONE) {
pauseAlarm()
return
}
val ringtone = when (alarmLevel) {
AlarmLevel.NONE -> null
AlarmLevel.MEDIUM -> mediumLevelRingtone

View File

@@ -38,19 +38,13 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.NordicLogger
import no.nordicsemi.android.common.logger.NordicLoggerFactory
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel
import no.nordicsemi.android.kotlin.ble.profile.prx.PRXData
import no.nordicsemi.android.prx.data.PRXServiceData
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.DisconnectAndStopEvent
import no.nordicsemi.android.service.LinkLossResult
import no.nordicsemi.android.service.ServiceManager
import no.nordicsemi.android.service.SuccessResult
import no.nordicsemi.android.ui.view.StringConst
import javax.inject.Inject
import javax.inject.Singleton
@@ -58,8 +52,7 @@ import javax.inject.Singleton
class PRXRepository @Inject internal constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager,
private val alarmHandler: AlarmHandler,
private val serviceManager: ServiceManager
) {
private val _data = MutableStateFlow(PRXServiceData())
@@ -81,8 +74,8 @@ class PRXRepository @Inject internal constructor(
_data.value = _data.value.copy(deviceName = device.name)
}
fun onConnectionStateChanged(connectionState: GattConnectionState?) {
_data.value = _data.value.copy(connectionState = connectionState)
fun onConnectionStateChanged(connection: Pair<GattConnectionState, BleGattConnectionStatus>) {
_data.value = _data.value.copy(connectionState = connection.first, connectionStatus = connection.second)
}
fun setLocalAlarmLevel(alarmLevel: AlarmLevel) {
@@ -93,20 +86,6 @@ class PRXRepository @Inject internal constructor(
_data.value = _data.value.copy(linkLossAlarmLevel = alarmLevel)
}
private fun handleLocalAlarm(result: BleManagerResult<PRXData>) {
(result as? SuccessResult<PRXData>)?.let {
if (it.data.localAlarmLevel != AlarmLevel.NONE) {
alarmHandler.playAlarm(it.data.localAlarmLevel)
} else {
alarmHandler.pauseAlarm()
}
}
(result as? LinkLossResult<PRXData>)?.let {
val alarmLevel = it.data?.linkLossAlarmLevel ?: AlarmLevel.HIGH
alarmHandler.playAlarm(alarmLevel)
}
}
fun onBatteryLevelChanged(batteryLevel: Int) {
_data.value = _data.value.copy(batteryLevel = batteryLevel)
}

View File

@@ -149,17 +149,18 @@ internal class PRXService : NotificationService() {
linkLossCharacteristic.value
.mapNotNull { AlarmLevelParser.parse(it) }
.onEach { repository.setLocalAlarmLevel(it) }
.onEach { repository.setLinkLossAlarmLevel(it) }
.launchIn(lifecycleScope)
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@PRXService)
client.connectionState
client.connectionStateWithStatus
.filterNotNull()
.onEach { repository.onConnectionStateChanged(it) }
.filterNotNull()
.onEach { stopIfDisconnected(it) }
.onEach { stopIfDisconnected(it.first) }
.launchIn(lifecycleScope)
client.services

View File

@@ -32,11 +32,14 @@
package no.nordicsemi.android.prx.viewmodel
import android.os.ParcelUuid
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.analytics.AppAnalytics
@@ -47,6 +50,7 @@ import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel
import no.nordicsemi.android.prx.repository.AlarmHandler
import no.nordicsemi.android.prx.repository.PRXRepository
import no.nordicsemi.android.prx.repository.PRX_SERVICE_UUID
import no.nordicsemi.android.prx.view.DisconnectEvent
@@ -62,7 +66,8 @@ import javax.inject.Inject
internal class PRXViewModel @Inject constructor(
private val repository: PRXRepository,
private val navigationManager: Navigator,
private val analytics: AppAnalytics
private val analytics: AppAnalytics,
private val alarmHandler: AlarmHandler
) : ViewModel() {
val state = repository.data
@@ -75,10 +80,21 @@ internal class PRXViewModel @Inject constructor(
}
repository.data.onEach {
Log.d("AAATESTAAA", "Data $it")
if (it.isLinkLossDisconnected) {
alarmHandler.playAlarm(it.linkLossAlarmLevel)
}
if (it.connectionState == GattConnectionState.STATE_CONNECTED) {
analytics.logEvent(ProfileConnectedEvent(Profile.PRX))
}
}.launchIn(viewModelScope)
repository.data
.map { it.localAlarmLevel }
.distinctUntilChanged()
.onEach { alarmHandler.playAlarm(it) }
.launchIn(viewModelScope)
}
private fun requestBluetoothDevice() {
@@ -108,6 +124,7 @@ internal class PRXViewModel @Inject constructor(
private fun disconnect() {
repository.release()
alarmHandler.pauseAlarm()
navigationManager.navigateUp()
}
}