Making Battery Service optional (#133)

* Enabling battery service from mock GLS server

* Bugfix: Battery service is optional
This commit is contained in:
Aleksander Nowakowski
2023-12-21 23:00:44 +01:00
committed by GitHub
parent 1004a561fd
commit ff192aee43
10 changed files with 81 additions and 72 deletions

View File

@@ -152,14 +152,6 @@ internal class BPSViewModel @Inject constructor(
val bpsService = services.findService(BPS_SERVICE_UUID)!!
val bpmCharacteristic = bpsService.findCharacteristic(BPM_CHARACTERISTIC_UUID)!!
val icpCharacteristic = bpsService.findCharacteristic(ICP_CHARACTERISTIC_UUID)
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { onDataUpdate(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope)
bpmCharacteristic.getNotifications()
.mapNotNull { BloodPressureMeasurementParser.parse(it) }
@@ -172,6 +164,15 @@ internal class BPSViewModel @Inject constructor(
?.onEach { onDataUpdate(it) }
?.catch { it.printStackTrace() }
?.launchIn(viewModelScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { onDataUpdate(it) }
?.catch { it.printStackTrace() }
?.launchIn(viewModelScope)
}
private fun onMissingServices() {

View File

@@ -160,14 +160,6 @@ internal class CGMService : NotificationService() {
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)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
measurementCharacteristic.getNotifications()
.mapNotNull { CGMMeasurementParser.parse(it) }
@@ -213,6 +205,15 @@ internal class CGMService : NotificationService() {
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
lifecycleScope.launchWithCatch {
val featuresEnvelope = featureCharacteristic.read().let { CGMFeatureParser.parse(it) }!!
secured = featuresEnvelope.features.e2eCrcSupported

View File

@@ -110,14 +110,6 @@ internal class CSCService : NotificationService() {
private suspend fun configureGatt(services: ClientBleGattServices) {
val cscService = services.findService(CSC_SERVICE_UUID)!!
val cscMeasurementCharacteristic = cscService.findCharacteristic(CSC_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
val cscDataParser = CSCDataParser()
cscMeasurementCharacteristic.getNotifications()
@@ -125,6 +117,15 @@ internal class CSCService : NotificationService() {
.onEach { repository.onCSCDataChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
}
private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) {

View File

@@ -225,7 +225,7 @@ class GlsServer @Inject constructor(
)!!
startGlsService()
// startBatteryService()
startBatteryService()
}
private fun startGlsService() {

View File

@@ -208,14 +208,6 @@ internal class GLSViewModel @Inject constructor(
val glsService = services.findService(GLS_SERVICE_UUID)!!
glucoseMeasurementCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CHARACTERISTIC)!!
recordAccessControlPointCharacteristic = glsService.findCharacteristic(RACP_CHARACTERISTIC)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { _state.value = _state.value.copyWithNewBatteryLevel(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope)
glucoseMeasurementCharacteristic.getNotifications()
.mapNotNull { GlucoseMeasurementParser.parse(it) }
@@ -234,6 +226,15 @@ internal class GLSViewModel @Inject constructor(
.onEach { onAccessControlPointDataReceived(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { _state.value = _state.value.copyWithNewBatteryLevel(it) }
?.catch { it.printStackTrace() }
?.launchIn(viewModelScope)
}
private fun onAccessControlPointDataReceived(data: RecordAccessControlPointData) = viewModelScope.launch {

View File

@@ -115,23 +115,24 @@ internal class HRSService : NotificationService() {
val hrsService = services.findService(HRS_SERVICE_UUID)!!
val hrsMeasurementCharacteristic = hrsService.findCharacteristic(HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID)!!
val bodySensorLocationCharacteristic = hrsService.findCharacteristic(BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
val bodySensorLocation = bodySensorLocationCharacteristic.read()
BodySensorLocationParser.parse(bodySensorLocation)?.let { repository.onBodySensorLocationChanged(it) }
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
hrsMeasurementCharacteristic.getNotifications()
.mapNotNull { HRSDataParser.parse(it) }
.onEach { repository.onHRSDataChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
}
private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) {

View File

@@ -110,20 +110,21 @@ internal class HTSService : NotificationService() {
private suspend fun configureGatt(services: ClientBleGattServices) {
val htsService = services.findService(HTS_SERVICE_UUID)!!
val htsMeasurementCharacteristic = htsService.findCharacteristic(HTS_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
htsMeasurementCharacteristic.getNotifications()
.mapNotNull { HTSDataParser.parse(it) }
.onEach { repository.onHTSDataChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
}
private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) {

View File

@@ -198,14 +198,15 @@ internal class PRXService : NotificationService() {
alertLevelCharacteristic = prxService.findCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID)!!
val linkLossService = services.findService(LINK_LOSS_SERVICE_UUID)!!
val linkLossCharacteristic = linkLossService.findCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
tryOrLog {
linkLossCharacteristic.write(AlertLevelInputParser.parse(AlarmLevel.HIGH))

View File

@@ -110,20 +110,21 @@ internal class RSCSService : NotificationService() {
private suspend fun configureGatt(services: ClientBleGattServices) {
val rscsService = services.findService(RSCS_SERVICE_UUID)!!
val rscsMeasurementCharacteristic = rscsService.findCharacteristic(RSC_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!
val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!!
batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) }
.onEach { repository.onBatteryLevelChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
rscsMeasurementCharacteristic.getNotifications()
.mapNotNull { RSCSDataParser.parse(it) }
.onEach { repository.onRSCSDataChanged(it) }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
}
private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) {

View File

@@ -125,14 +125,6 @@ internal class UARTService : NotificationService() {
val rxCharacteristic = uartService.findCharacteristic(UART_RX_CHARACTERISTIC_UUID)!!
val txCharacteristic = uartService.findCharacteristic(UART_TX_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)
batteryService?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
txCharacteristic.getNotifications()
.map { String(it.value) }
.onEach { repository.onNewMessageReceived(it) }
@@ -146,6 +138,15 @@ internal class UARTService : NotificationService() {
.onEach { repository.log(10, "Sent: $it") }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
// Battery service is optional
services.findService(BATTERY_SERVICE_UUID)
?.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)
?.getNotifications()
?.mapNotNull { BatteryLevelParser.parse(it) }
?.onEach { repository.onBatteryLevelChanged(it) }
?.catch { it.printStackTrace() }
?.launchIn(lifecycleScope)
}
private fun getWriteType(characteristic: ClientBleGattCharacteristic): BleWriteType {