Enviar datos a través del aire y, una vez finalizada la operación, finalizarla utilizando RxAndroidBLE.
Estoy tratando de enviar los 128
bytes del bloque al controlador BLE usando la biblioteca RxAndroidBle
. El flujo para enviar datos desde el móvil al controlador BLE es el siguiente:
- Conectar con el controlador BLE
- Iniciar OTA (enviar 1)
- Enviar CRC (del bloque de datos)
- Enviar bloque de datos
- Esperar 2 segundos
- Repetir paso 3
- FINALIZAR OTA (enviar 2)
Aquí hay una captura de código:
.flatMap(rxBleConnection -> prepareWriting())
.flatMapIterable(otaMetaData -> otaMetaData)
.zipWith(Observable.interval(2, TimeUnit.SECONDS), (item, interval) -> item)
.doOnNext(metaData -> {
otaMetaData = metaData;
})
.map(otaMetaData -> {
return mRxBleConnection.writeCharacteristic(OTA_CHECKSUM, otaMetaData.getCrcBlock()).toObservable();
})
.doOnNext(otaMetaData -> {
Log.e(TAG, "Escribiendo CRC " + Arrays.toString(BLEUtils.toHex(otaMetaData.getCrcBlock())));
})
.map(bytes -> {
return mRxBleConnection.writeCharacteristic(OTA_DATA, otaMetaData.getDataBlock()).toObservable();
})
.doOnNext(otaMetaData -> {
Log.e(TAG, "Escribiendo Datos " + Arrays.toString(BLEUtils.toHex(otaMetaData.getDataBlock())));
})
.flatMap(bytes -> mRxBleConnection.writeCharacteristic(OTA_CONTROL,OTA_DATA_END).toObservable())
El problema ocurre al enviar el comando FINALIZAR OTA
debido a que, al retornar 20
elementos, .flatMap(bytes -> mRxBleConnection.writeCharacteristic(OTA_CONTROL,OTA_DATA_END)
se llama 20
veces.
Por lo tanto, no estoy seguro de cómo puedo enviar el comando OTA_DATA_END
cuando todos los 20
elementos se procesen. Además, cualquier sugerencia para mejorar el código existente es bienvenida.
davy.ai
Para enviar el comando
OTA_DATA_END
después de que se hayan procesado los 20 elementos, puedes usar el operadortoList()
después deflatMapIterable()
para convertir los elementos emitidos en una sola lista. Luego, puedes usar el operadordoOnSuccess()
para activar una acción después de que se complete la lista, y finalmente llamarmRxBleConnection.writeCharacteristic(OTA_CONTROL, OTA_DATA_END)
para enviar el comandoOTA_DATA_END
.Aquí tienes un fragmento de código actualizado:
En cuanto a mejorar el código existente, aquí hay algunas sugerencias:
compose()
para extraer la lógica común en operadores reutilizables. Por ejemplo, podrías crear un operador que maneje las llamadas awriteCharacteristic()
y el registro de eventos, y aplicarlo tanto a las escrituras de checksum como a las de bloque de datos.Reemplaza las llamadas a
doOnNext()
con operadores que puedan modificar los elementos emitidos en línea, comomap()
,flatMap()
, oflatMapSingle()
. Esto hará que el código sea más componible y más fácil de entender.Usa constantes o enums para los valores de
OTA_CHECKSUM
,OTA_DATA
yOTA_CONTROL
, para que puedan modificarse fácilmente si es necesario.Considera dividir el método
prepareWriting()
en métodos u operadores más pequeños, para mejorar la legibilidad y testabilidad. Por ejemplo, podrías crear un operador que lea los datos del firmware desde un archivo y los convierta en una lista de objetosOtaMetaData
.En general, el código se ve bien y sigue el patrón recomendado de utilizar streams reactivos para manejar eventos asíncronos de manera limpia y componible. ¡Buen trabajo!