From e0de31c65e631558f1d9a95b7bc2d45f4f1a2580 Mon Sep 17 00:00:00 2001 From: chandrashekhar reddy Date: Tue, 5 Mar 2024 11:47:36 +0530 Subject: [PATCH] merging all version in one --- .../example/hpostesting/data/DataHolder.kt | 3 + .../hpostesting/data/api/PropertyProvider.kt | 3 +- .../hpostesting/data/constant/Constants.kt | 15 + .../data/constant/HemoCubeCommands.kt | 19 +- .../data/constant/TrueHemeCommands.kt | 18 + .../hpostesting/data/dao/MyDataBase.kt | 6 +- .../hpostesting/data/dao/TrueHemeDao.kt | 36 + .../data/datasource/LocalFileDataSource.kt | 5 + .../data/model/TestStateTrueHeme.kt | 44 + .../data/model/molbioresult/MolbioV2Result.kt | 3 +- .../data/model/patient/TrueHemeTestData.kt | 94 ++ .../data/model/patient/UserData.kt | 14 + .../data/repository/DatabaseRepository.kt | 16 + .../hpostesting/data/repository/Repository.kt | 2 + .../hpostesting/domain/di/AppModule.kt | 7 + .../presentation/KitScanActivity.kt | 3 +- .../adapter/OfflineUserListAdapter.kt | 7 +- .../presentation/adapter/UserListAdapter.kt | 2 +- .../assurance/AssuranceControlsFragment.kt | 5 +- .../dashboard/DashboardActivity.kt | 5 +- .../presentation/dashboard/HomeFragment.kt | 98 +- .../DeviceProvisionActivity.kt | 7 +- .../DeviceProvisionFragment.kt | 5 +- .../presentation/hemocube/HemoCubeFragment.kt | 1227 ++++------------- .../hemocube/HemoCubeViewModel.kt | 461 +------ .../presentation/hemocube/HemocubeActivity.kt | 21 +- .../presentation/testRight/UsbService.kt | 16 + .../presentation/trueheme/TrueHemeActivity.kt | 41 +- .../presentation/trueheme/TrueHemeFragment.kt | 467 ++++--- .../trueheme/TrueHemeViewModel.kt | 188 +-- 30 files changed, 1056 insertions(+), 1782 deletions(-) create mode 100644 app/src/main/java/com/example/hpostesting/data/constant/TrueHemeCommands.kt create mode 100644 app/src/main/java/com/example/hpostesting/data/dao/TrueHemeDao.kt create mode 100644 app/src/main/java/com/example/hpostesting/data/model/TestStateTrueHeme.kt create mode 100644 app/src/main/java/com/example/hpostesting/data/model/patient/TrueHemeTestData.kt diff --git a/app/src/main/java/com/example/hpostesting/data/DataHolder.kt b/app/src/main/java/com/example/hpostesting/data/DataHolder.kt index 0996c42..4e81b36 100644 --- a/app/src/main/java/com/example/hpostesting/data/DataHolder.kt +++ b/app/src/main/java/com/example/hpostesting/data/DataHolder.kt @@ -2,6 +2,7 @@ package com.example.hpostesting.data import androidx.lifecycle.MutableLiveData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestType @@ -23,8 +24,10 @@ object DataHolder { val intensityReferenceArray = ArrayList() var selectedTest: UserData? = null var hemoCubeTestData: HemoCubeTestData? = null + var trueHemeTestData: TrueHemeTestData? = null var kitSerial: String = "" var location: UserData.Location? = null var testExp: Boolean = true var hemocubeResult: Double? = null + var trueHemeResult: Double? = null } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt b/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt index 12486ec..a89b2e7 100644 --- a/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt +++ b/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt @@ -1,6 +1,7 @@ package com.example.hpostesting.data.api import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.presentation.UsbServiceListener interface PropertyProvider { @@ -9,5 +10,5 @@ interface PropertyProvider { } interface DeviceCommunicationHandler { - fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) + fun sendAndListenToDevice(command: TrueHemeCommands, listener: UsbServiceListener) } diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 56cec54..596e9af 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -3,6 +3,7 @@ package com.example.hpostesting.data.constant object Constants { const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION" + const val TRUEHEME_USB_PERMISSION = "shanmukha.in.sickle_cell_trueheme.USB_PERMISSION" const val BASE_URL = "www.google.com" const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb" @@ -239,6 +240,20 @@ object Constants { const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_UPPER_BOUND = 23500 + const val TEST_STATUS_CODE_TEST_STARTED = 1.0 + const val TEST_STATUS_CODE_CONFIG_STARTED = 2.0 + const val TEST_STATUS_CODE_CONFIG_COMPLETED = 3.0 + const val TEST_STATUS_CODE_BUFFER_STARTED = 4.0 + const val TEST_STATUS_CODE_BUFFER_COMPLETED = 5.0 + const val TEST_STATUS_CODE_BUFFER_PRINT_STARTED = 6.0 + const val TEST_STATUS_CODE_BUFFER_PRINT_COMPLETED = 7.0 + const val TEST_STATUS_CODE_SAMPLE_STARTED = 8.0 + const val TEST_STATUS_CODE_SAMPLE_COMPLETED = 9.0 + const val TEST_STATUS_CODE_SAMPLE_PRINT_STARTED = 10.0 + const val TEST_STATUS_CODE_SAMPLE_PRINT_COMPLETED = 11.0 + const val TEST_STATUS_CODE_TEST_COMPLETED = 12.0 + + val DEVICE_CONFIGURATION: Map>> = mapOf>>( "HCV-000-3001" to listOf( listOf(1.0, 0.0), // LED1, 435nm diff --git a/app/src/main/java/com/example/hpostesting/data/constant/HemoCubeCommands.kt b/app/src/main/java/com/example/hpostesting/data/constant/HemoCubeCommands.kt index 5edd02b..1a806e2 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/HemoCubeCommands.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/HemoCubeCommands.kt @@ -1,18 +1,9 @@ package com.example.hpostesting.data.constant enum class HemoCubeCommands(val command: String) { - START_BUFFER_COMMAND("B\r"), - AUTO_DAC_COMMAND("C\r"), - SET_AUTO_DAC_TO_EPROM_COMMAND("G\r"), - DIAGNOSTICS_COMMAND("D\r"), - FIRMWARE_INFO_COMMAND("F\r"), - START_SAMPLE("S\r"), - PRINT_COMMAND("P\r"), - READ_DAC_COMMAND("R\r"), - DEVICE_CONFIGURATION_COMMAND("I\r"), - LOAD_DAC_VALUES("E\r"), - FIRST_GAIN_COMMAND("T\r"), - SECOND_GAIN_COMMAND("U\r"), - THIRD_GAIN_COMMAND("V\r"), - FORTH_GAIN_COMMAND("W\r"), + startBuffer("B\r"), + runDiagnostics("D\r"), + startSample("S\r"), + getSample("P\r"), + getDeviceId("I\r"), } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/constant/TrueHemeCommands.kt b/app/src/main/java/com/example/hpostesting/data/constant/TrueHemeCommands.kt new file mode 100644 index 0000000..11b0ad1 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/constant/TrueHemeCommands.kt @@ -0,0 +1,18 @@ +package com.example.hpostesting.data.constant + +enum class TrueHemeCommands(val command: String) { + START_BUFFER_COMMAND("B\r"), + AUTO_DAC_COMMAND("C\r"), + SET_AUTO_DAC_TO_EPROM_COMMAND("G\r"), + DIAGNOSTICS_COMMAND("D\r"), + FIRMWARE_INFO_COMMAND("F\r"), + START_SAMPLE("S\r"), + PRINT_COMMAND("P\r"), + READ_DAC_COMMAND("R\r"), + DEVICE_CONFIGURATION_COMMAND("I\r"), + LOAD_DAC_VALUES("E\r"), + FIRST_GAIN_COMMAND("T\r"), + SECOND_GAIN_COMMAND("U\r"), + THIRD_GAIN_COMMAND("V\r"), + FORTH_GAIN_COMMAND("W\r"), +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt index a5e10be..ad74ef7 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -6,16 +6,18 @@ import androidx.room.TypeConverters import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData @Database( - entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class], - version = 28, + entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class,TrueHemeTestData::class], + version = 29, exportSchema = false ) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao abstract fun hemoCubeDao(): HemoCubeDao + abstract fun trueHemeDao(): TrueHemeDao abstract fun hemoCubeBufferDao(): HemoCubeBufferDao } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/TrueHemeDao.kt b/app/src/main/java/com/example/hpostesting/data/dao/TrueHemeDao.kt new file mode 100644 index 0000000..670cf66 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/dao/TrueHemeDao.kt @@ -0,0 +1,36 @@ +package com.example.hpostesting.data.dao + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.example.hpostesting.data.model.patient.TrueHemeTestData + +@Dao +interface TrueHemeDao { + @Query("SELECT * from true_heme_test_table") + fun getAll(): LiveData> + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(trueHemeTestData: TrueHemeTestData) + + @Query("SELECT * FROM true_heme_test_table WHERE _id = :id") + suspend fun getUserByID(id: String): TrueHemeTestData + + @Query("DELETE FROM true_heme_test_table WHERE _id = :id") + suspend fun deleteById(id: String) + + @Query("UPDATE true_heme_test_table SET localFlag = :newValue WHERE _id = :id") + suspend fun updateFieldById(id: String, newValue: Boolean) + + @Query("UPDATE true_heme_test_table SET molbioFlag = :newValue WHERE _id = :id") + suspend fun updateMolbioFlag(id: String, newValue: Boolean) + + @Query("UPDATE true_heme_test_table SET isCSVCreated = :newValue WHERE _id = :id") + suspend fun updateCSVFieldById(id: String, newValue: Boolean) + + @Query("SELECT * from true_heme_test_table WHERE molbioFlag = :status") + suspend fun getPendingUser(status: Boolean): List + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt index 4983c11..2caed0a 100644 --- a/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt +++ b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt @@ -1,6 +1,7 @@ package com.example.hpostesting.data.datasource import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData interface LocalFileDataSource { @@ -11,4 +12,8 @@ interface LocalFileDataSource { fun exportDataToCSV( fileName: String, dataList: List, ): Boolean + + fun exportDataToCSV( + fileName: String, dataList: List, + ): Boolean } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/model/TestStateTrueHeme.kt b/app/src/main/java/com/example/hpostesting/data/model/TestStateTrueHeme.kt new file mode 100644 index 0000000..2d60eda --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/model/TestStateTrueHeme.kt @@ -0,0 +1,44 @@ +package com.example.hpostesting.data.model + +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.patient.DeviceData +import com.example.hpostesting.data.model.patient.TrueHemeTestData + +data class TestStateTrueHeme ( + var testDetails: TrueHemeTestData? = null, + var isOnline: Boolean = false, + var currentDeviceData: DeviceData? = null, + var resultData: String = "", + var currentResultData: String = "", + var isUsingExistingBuffer: Boolean = false, + var isTestOngoing: Boolean = false, + var led1BufferForDevice: Double = 0.0, + var led2BufferForDevice: Double = 0.0, + var led3BufferForDevice: Double = 0.0, + var led4BufferForDevice: Double = 0.0, + var led1SampleForDevice: Double = 0.0, + var led2SampleForDevice: Double = 0.0, + var led3SampleForDevice: Double = 0.0, + var led4SampleForDevice: Double = 0.0, + var fittedAbs1: Double = 0.0, + var fittedAbs2: Double = 0.0, + var fittedAbs3: Double = 0.0, + var fittedAbs4: Double = 0.0, +// var led1Air1: Double? = null, +// var led2Air1: Double? = null, +// var led3Air1: Double? = null, +// var led4Air1: Double? = null, +// var led1Air2: Double? = null, +// var led2Air2: Double? = null, +// var led3Air2: Double? = null, +// var led4Air2: Double? = null, + var calculatedPredictedDenovixRatio: Double = 0.0, + var validationError: Boolean = false, + var deviceHardwareId: String = "", + var allErrorMessages: String = "", + var testStatusCode: Double = 0.0, + var repeatReadingCount: Int = 0, + var readingsPerSample: Int = Constants.READINGS_PER_SAMPLE, + var uploadedToCloud: Boolean = false, + var uploadedToMolbio: Boolean = false +) \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/model/molbioresult/MolbioV2Result.kt b/app/src/main/java/com/example/hpostesting/data/model/molbioresult/MolbioV2Result.kt index 137a627..ea179a7 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/molbioresult/MolbioV2Result.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/molbioresult/MolbioV2Result.kt @@ -1,6 +1,7 @@ package com.example.hpostesting.data.model.molbioresult import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData data class MolbioV2Result( val age: Int? = 31, @@ -22,7 +23,7 @@ data class MolbioV2Result( val `operator`: String? = "", val patientId: Int? = 4545, val pregnancy: Boolean? = false, - val rawData: HemoCubeTestData? = HemoCubeTestData(), + val rawData: TrueHemeTestData? = TrueHemeTestData(), val recommendation: String? = "NA", val sampleId: String? = "", val sampleType: String? = "", diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/TrueHemeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/TrueHemeTestData.kt new file mode 100644 index 0000000..3de9bd8 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/TrueHemeTestData.kt @@ -0,0 +1,94 @@ +package com.example.hpostesting.data.model.patient + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "true_heme_test_table") +data class TrueHemeTestData( + @PrimaryKey + var _id: String = "", + var name: String = "", + var incubationTime: String = "", + var bloodGroup: String = "", + var birthYear: String = "", + var state: String = "", + var abhaId: String = "", + var userImageURL: String = "", + var location: UserData.Location? = null, + var reportUploadTime: String? = "", + var testType: String? = "TRUEHEME", + var testTime: String? = "", + var testStatus: Boolean? = false, + var gender: String = "", + var localFlag: Boolean = false, + var deviceId: String? = "", + var appVersion: String? = "", + var deviceSerialNumber: String = "", + var deviceType: String = "TRUEHEME", + var kitSerial: String = "", + var resultData: String = "", + var led1Buffer: Double? = null, + var led2Buffer: Double? = null, + var led3Buffer: Double? = null, + var led4Buffer: Double? = null, + var led1Sample: Double? = null, + var led2Sample: Double? = null, + var led3Sample: Double? = null, + var led4Sample: Double? = null, + var led1Average: Double? = null, + var led2Average: Double? = null, + var led3Average: Double? = null, + var led4Average: Double? = null, + var abs1: Double? = null, + var abs2: Double? = null, + var abs3: Double? = null, + var abs4: Double? = null, + var hb3: Double? = null, + var hb4: Double? = null, + var led1Gain1: Double? = null, + var led2Gain1: Double? = null, + var led3Gain1: Double? = null, + var led4Gain1: Double? = null, + var led1Gain2: Double? = null, + var led2Gain2: Double? = null, + var led3Gain2: Double? = null, + var led4Gain2: Double? = null, + var led1Gain3: Double? = null, + var led2Gain3: Double? = null, + var led3Gain3: Double? = null, + var led4Gain3: Double? = null, + var led1Gain4: Double? = null, + var led2Gain4: Double? = null, + var led3Gain4: Double? = null, + var led4Gain4: Double? = null, + var led1Air1: Double? = null, + var led2Air1: Double? = null, + var led3Air1: Double? = null, + var led4Air1: Double? = null, + var led1Air2: Double? = null, + var led2Air2: Double? = null, + var led3Air2: Double? = null, + var led4Air2: Double? = null, + var deviceRatio: Double? = null, + var calculatedRatio: Double? = null, + var predictedDenovixRatio: Double? = null, + var slopeRatio: Double? = null, + var coefficients: String? = "", + var classificationResult: String = "", + var prdClassification: String = "", + var deviceRatioClass: String = "", + var slopeRatioClass: String = "", + var borderlineMethod2Class: String = "", + var errorMessages: String = "", + var batteryLevel: String = "", + var batteryCapacity: String = "", + var batteryMaxCapacity: String = "", + var batteryTemperature: String = "", + var batteryVoltage: String = "", + var molbioFlag: Boolean = false, + var quickCapture: Boolean = false, + var solution: String? = "", + var concentration: String? = "", + var volume: String? = "", + var isCSVCreated: Boolean = false, +) diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt index 260c447..7ab8a19 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt @@ -57,3 +57,17 @@ fun UserData.toHemoCubeTestData() = HemoCubeTestData( prdClassification = prdClassification, testTime = testTime ) +fun UserData.toTrueHemeTestData() = TrueHemeTestData( + _id = _id, + name = name, + bloodGroup = bloodGroup, + birthYear = birthYear, + gender = gender, + state = state, + abhaId = abhaId, + userImageURL = userImageURL, + testStatus = testStatus, + location = location, + prdClassification = prdClassification, + testTime = testTime +) diff --git a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt index 4c49cc8..7eba9f3 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt @@ -20,6 +20,7 @@ import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateResponse @@ -107,6 +108,21 @@ class DatabaseRepository @Inject constructor( Response.Error(e) } } + override suspend fun addTestToDatabaseTrue(data: TrueHemeTestData?): Response { + return try { + val userdata = + db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() + if (userdata.documents.isNotEmpty()) { + userdata.documents.forEach { + db.collection("patientData").document(it.id).update("testStatus", true) + } + } + db.collection("testData").add(data).await() + Response.Success(data._id) + } catch (e: Exception) { + Response.Error(e) + } + } override suspend fun addTestToDatabase(data: UserData?): Response { return try { diff --git a/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt index 8c3f995..57f58f8 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt @@ -16,6 +16,7 @@ import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateResponse @@ -25,6 +26,7 @@ import okhttp3.ResponseBody interface Repository { suspend fun addTestToDatabase(data: HemoCubeTestData?): Response + suspend fun addTestToDatabaseTrue(data: TrueHemeTestData?): Response suspend fun addTestToDatabase(data: UserData?): Response diff --git a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt index d7babfd..069beff 100644 --- a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt +++ b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt @@ -11,6 +11,7 @@ import com.example.hpostesting.data.api.PropertyProvider import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.MyDatabase +import com.example.hpostesting.data.dao.TrueHemeDao import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.datasource.LocalFileDataSource import com.example.hpostesting.data.datasource.LocalFileDataSourceImpl @@ -61,6 +62,12 @@ object AppModule { return myDatabase.hemoCubeDao() } + @Provides + @Singleton + fun provideMyTrueHeme(myDatabase: MyDatabase): TrueHemeDao { + return myDatabase.trueHemeDao() + } + @Provides @Singleton fun provideMyHemoCubeBuffer(myDatabase: MyDatabase): HemoCubeBufferDao { diff --git a/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt index ad6169a..b99545b 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt @@ -16,6 +16,7 @@ import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.testRight.TestRightActivity +import com.example.hpostesting.presentation.trueheme.TrueHemeActivity import com.google.android.material.snackbar.Snackbar import com.google.firebase.crashlytics.FirebaseCrashlytics import com.journeyapps.barcodescanner.ScanContract @@ -296,7 +297,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { } Constants.DEVICE_TYPE_TRUEHEME -> { - val i = Intent(applicationContext, HemocubeActivity::class.java) + val i = Intent(applicationContext, TrueHemeActivity::class.java) startActivity(i) } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt index bae6504..b8cb7f8 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt @@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding @@ -29,15 +30,15 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) RecyclerView.ViewHolder(binding.root) { } - private val differCallback = object : DiffUtil.ItemCallback() { + private val differCallback = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: HemoCubeTestData, newItem: HemoCubeTestData, + oldItem: TrueHemeTestData, newItem: TrueHemeTestData, ): Boolean { return oldItem._id == newItem._id } override fun areContentsTheSame( - oldItem: HemoCubeTestData, newItem: HemoCubeTestData, + oldItem: TrueHemeTestData, newItem: TrueHemeTestData, ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt index 7466e79..1f2f85d 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt @@ -30,7 +30,7 @@ import java.util.Locale class UserListAdapter( private val context: Context, - private val hemoCubeViewModel: HemoCubeViewModel, + // private val hemoCubeViewModel: HemoCubeViewModel, options: FirestoreRecyclerOptions, private val view: View, private val batLevel: Int, diff --git a/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt index d341e42..572100a 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt @@ -13,12 +13,11 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Spinner import android.widget.Toast -import androidx.core.view.isVisible import androidx.fragment.app.Fragment import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.model.patient.UserData -import com.example.hpostesting.presentation.hemocube.HemocubeActivity +import com.example.hpostesting.presentation.trueheme.TrueHemeActivity import `in`.sminnovations.hpostesting.databinding.FragmentAssuranceControlsBinding import java.time.Instant @@ -179,7 +178,7 @@ class AssuranceControlsFragment : Fragment() { apply() } - val i = Intent(requireContext(), HemocubeActivity::class.java) + val i = Intent(requireContext(), TrueHemeActivity::class.java) startActivity(i) } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt index f793da3..2a487da 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt @@ -28,6 +28,7 @@ import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.presentation.NatsManager import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.jig.JigActivity +import com.example.hpostesting.presentation.trueheme.TrueHemeViewModel import com.google.android.material.navigation.NavigationView import com.google.firebase.appdistribution.FirebaseAppDistribution import com.google.firebase.appdistribution.FirebaseAppDistributionException @@ -61,7 +62,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { lateinit var nats: NatsManager private var downloadId: Long = 0 // TODO: Remove hemocube viewmodel - private val hemocubeViewModel: HemoCubeViewModel by viewModels() + private val truehemeViewModel: TrueHemeViewModel by viewModels() override fun attachBaseContext(newBase: Context?) { val languageCode = LanguageManager.getSavedLanguage(newBase!!) @@ -92,7 +93,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { nats.sub("server.hpos.${deviceId}.ping") nats.pub("server.hpos.${deviceId}.ping", "THIS IS A TEST MSG") - hemocubeViewModel.deviceUpdate.observe(this) { result -> + truehemeViewModel.deviceUpdate.observe(this) { result -> when (result) { is Result.Success -> { // Handle success diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt index f60891f..66e3008 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -30,12 +30,14 @@ import com.example.hpostesting.data.Result import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.molbioresult.MolbioV2Result import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest @@ -46,6 +48,7 @@ import com.example.hpostesting.presentation.adapter.UserListAdapter import com.example.hpostesting.presentation.assurance.AssuranceControlsActivity import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.testRight.TestRightViewModel +import com.example.hpostesting.presentation.trueheme.TrueHemeViewModel import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.firestore.Query @@ -76,12 +79,13 @@ class HomeFragment : Fragment() { private var downloadId: Long = 0 private lateinit var binding: FragmentHomeBinding private val viewModel: TestRightViewModel by activityViewModels() - private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() + // private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() + private val trueHemeViewModel: TrueHemeViewModel by activityViewModels() private lateinit var rvAdapter: UserListAdapter private var batLevel: Int = 0 // Initialize with a default value, or obtain the actual battery level private lateinit var adapter: OfflineUserListAdapter - private val homeViewModel: HemoCubeViewModel by activityViewModels() + // private val homeViewModel: HemoCubeViewModel by activityViewModels() private var isTokenAvailable = false private var natsToken: String = "" @@ -113,10 +117,10 @@ class HomeFragment : Fragment() { viewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteIncompleteRegistrations(userData) } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteHemoCubeIncompleteRegistrations(userData) if (userData.isNotEmpty()) { - val userList = mutableListOf() + val userList = mutableListOf() userData.forEach { if (it.testStatus == false) { userList.add(it) @@ -148,7 +152,7 @@ class HomeFragment : Fragment() { checkForTokenAndUpdate() } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result())) userDataList.forEach { userData -> if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) { @@ -169,12 +173,12 @@ class HomeFragment : Fragment() { } if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) { userData.molbioFlag = true - hemoCubeViewModel.uploadResult(resultList) + trueHemeViewModel.uploadResult(resultList) } if (!userData.localFlag) { userData.localFlag = true - hemoCubeViewModel.bulkAddResultTestToDb(userData) + trueHemeViewModel.bulkAddResultTestToDb(userData) } } @@ -188,7 +192,7 @@ class HomeFragment : Fragment() { setUserId() } } - hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result -> + trueHemeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result -> if (result == "Success") { Toast.makeText( requireContext(), R.string.test_upload, Toast.LENGTH_SHORT @@ -206,7 +210,7 @@ class HomeFragment : Fragment() { binding.uploadData.setOnClickListener { showUploadDialog(requireContext()) } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> val btnSaveLocalVisibility = if (userData.any { it.testStatus == true }) View.GONE else View.GONE @@ -260,17 +264,17 @@ class HomeFragment : Fragment() { deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString() if (userID.isNotEmpty() && password.isNotEmpty()) { if (!isTokenAvailable) { - hemoCubeViewModel.login(createLoginRequestData(userID, password)) + trueHemeViewModel.login(createLoginRequestData(userID, password)) } else { if (isTokenExpired(accessToken)) { - hemoCubeViewModel.login(createLoginRequestData(userID, password)) + trueHemeViewModel.login(createLoginRequestData(userID, password)) } else { isTokenAvailable = true - hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) - hemoCubeViewModel.uploadLogs() - hemoCubeViewModel.startPeriodicCheckUpdate() - hemoCubeViewModel.downloadClientCertificate() + trueHemeViewModel.deviceUpdate(createDeviceUpdateRequestData()) + trueHemeViewModel.uploadLogs() + trueHemeViewModel.startPeriodicCheckUpdate() + trueHemeViewModel.downloadClientCertificate() } } } else if (deviceId.isNotEmpty()) { @@ -280,13 +284,13 @@ class HomeFragment : Fragment() { password = sharedPreference.getString("password", "").toString() accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() if (accessToken.isEmpty()) { - hemoCubeViewModel.login(createLoginRequestData(userID, password)) + trueHemeViewModel.login(createLoginRequestData(userID, password)) } else { // Continue with your existing logic if the token is not empty. isTokenAvailable = true - hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) - hemoCubeViewModel.uploadLogs() - hemoCubeViewModel.startPeriodicCheckUpdate() + trueHemeViewModel.deviceUpdate(createDeviceUpdateRequestData()) + trueHemeViewModel.uploadLogs() + trueHemeViewModel.startPeriodicCheckUpdate() } } else { Toast.makeText( @@ -296,7 +300,7 @@ class HomeFragment : Fragment() { ).show() } - hemoCubeViewModel.loginResponse.observe(viewLifecycleOwner) { response -> + trueHemeViewModel.loginResponse.observe(viewLifecycleOwner) { response -> when (response) { is Result.Success -> { updateTokens(response) @@ -321,7 +325,7 @@ class HomeFragment : Fragment() { } } - hemoCubeViewModel.uploadLogs.observe(viewLifecycleOwner) { response -> + trueHemeViewModel.uploadLogs.observe(viewLifecycleOwner) { response -> when (response) { is Result.Success -> { // Toast.makeText( @@ -350,7 +354,7 @@ class HomeFragment : Fragment() { } } - hemoCubeViewModel.downloadcertificate.observe(viewLifecycleOwner) { response -> + trueHemeViewModel.downloadcertificate.observe(viewLifecycleOwner) { response -> when (response) { is Result.Success -> { val url = response.data @@ -393,12 +397,12 @@ class HomeFragment : Fragment() { } } - hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { + trueHemeViewModel.resultUpload.observe(viewLifecycleOwner) { when (it) { is Result.Success -> { it.data.data?.forEach { id -> id.rawData?.let { it1 -> - hemoCubeViewModel.updateMolbioFlag( + trueHemeViewModel.updateMolbioFlag( it1._id ) } @@ -533,8 +537,8 @@ class HomeFragment : Fragment() { val userId = binding.userId.text.toString() val bloodGroup = binding.etBloodGroup.text if (userId.length >= 10 && !bloodGroup.equals("Select Blood Group") || !bloodGroup.isNullOrBlank()) { - hemoCubeViewModel.addUser( - HemoCubeTestData( + trueHemeViewModel.addUser( + TrueHemeTestData( _id = userId, bloodGroup = bloodGroup.toString(), incubationTime = SimpleDateFormat( @@ -584,7 +588,7 @@ class HomeFragment : Fragment() { putString(Constants.NATS_TOKEN, natsToken) apply() } - hemoCubeViewModel.login(createLoginRequestData(username, password)) + trueHemeViewModel.login(createLoginRequestData(username, password)) } ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.") } else { Log.e("fetchDeviceCredentials", "Document does not exist.") @@ -625,7 +629,7 @@ class HomeFragment : Fragment() { rvAdapter = view?.let { UserListAdapter( requireContext(), - hemoCubeViewModel, + //trueHemeViewModel, recyclerViewOptions, it, batLevel, @@ -694,7 +698,7 @@ class HomeFragment : Fragment() { rvAdapter = view?.let { UserListAdapter( requireContext(), - hemoCubeViewModel, + // trueHemeViewModel, recyclerViewOptions, it, batLevel, @@ -752,13 +756,13 @@ class HomeFragment : Fragment() { binding.uploadData.visibility = uploadDataVisibility } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val uploadDataVisibility = if (userDataList.any { !it.localFlag && !it.molbioFlag && it.testStatus == true }) View.VISIBLE else View.GONE binding.uploadData.visibility = uploadDataVisibility } - hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { bufferData -> + trueHemeViewModel.allKitTestData.observe(viewLifecycleOwner) { bufferData -> val uploadDataVisibility = if (bufferData.any { !it.localFlag }) View.VISIBLE else View.GONE binding.uploadData.visibility = uploadDataVisibility @@ -766,7 +770,7 @@ class HomeFragment : Fragment() { } private fun checkUnprocessedCSVData() { - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val downloadDataVisibility = if (userDataList.any { !it.isCSVCreated && it.testStatus == true }) View.GONE else View.GONE binding.downloadCSV.visibility = downloadDataVisibility @@ -823,7 +827,7 @@ class HomeFragment : Fragment() { } } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result())) userDataList.forEach { userData -> if (!userData.molbioFlag && isTokenAvailable) { @@ -846,27 +850,27 @@ class HomeFragment : Fragment() { if (!userData.localFlag) { userData.localFlag = true - hemoCubeViewModel.bulkAddResultTestToDb(userData) + trueHemeViewModel.bulkAddResultTestToDb(userData) } if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) { userData.molbioFlag = true - hemoCubeViewModel.uploadResult(resultList) + trueHemeViewModel.uploadResult(resultList) } } dialog.dismiss() } - hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList -> + trueHemeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList -> kitDataList.forEach { userData -> if (!userData.localFlag) { userData.localFlag = true - hemoCubeViewModel.bulkAddResultKitTestToDb(userData) + trueHemeViewModel.bulkAddResultKitTestToDb(userData) } } dialog.dismiss() } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result())) userDataList.forEach { userData -> if (!userData.molbioFlag && isTokenAvailable) { @@ -885,12 +889,12 @@ class HomeFragment : Fragment() { ) ) userData.molbioFlag = true - hemoCubeViewModel.uploadResult(resultList) + trueHemeViewModel.uploadResult(resultList) } if (!userData.localFlag) { userData.localFlag = true - hemoCubeViewModel.bulkAddResultTestToDb(userData) + trueHemeViewModel.bulkAddResultTestToDb(userData) } } @@ -928,10 +932,10 @@ class HomeFragment : Fragment() { } } - private fun deleteHemoCubeIncompleteRegistrations(userDataList: List) { + private fun deleteHemoCubeIncompleteRegistrations(userDataList: List) { userDataList.forEach { userData -> if (userData._id.isEmpty()) { - hemoCubeViewModel.deleteById(userData._id) + trueHemeViewModel.deleteById(userData._id) } } } @@ -942,7 +946,7 @@ class HomeFragment : Fragment() { private fun downloadCsv() { context?.let { context -> - val success = homeViewModel.getLocalUserDataForCsv(context) + val success = trueHemeViewModel.getLocalUserDataForCsv(context) if (success) { // Provide feedback to the user if needed Toast.makeText(context, "CSV file downloaded successfully", Toast.LENGTH_SHORT) @@ -973,10 +977,10 @@ class HomeFragment : Fragment() { private fun downloadLocalDBData(dialog: DialogInterface) { var csvDownloaded = false - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + trueHemeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> try { if (!csvDownloaded) { - val downloadList = mutableListOf() + val downloadList = mutableListOf() userDataList.forEach { userData -> if (userData.testStatus == true) { @@ -988,7 +992,7 @@ class HomeFragment : Fragment() { if (downloadList.isNotEmpty()) { // Call ViewModel function to create CSV with filtered data - hemoCubeViewModel.createCSV(downloadList, requireContext()) + trueHemeViewModel.createCSV(downloadList, requireContext()) csvDownloaded = true Toast.makeText( requireContext(), @@ -1019,7 +1023,7 @@ class HomeFragment : Fragment() { Log.d("HomeFragmentUSb","getDeviceId") val handler = activity as? DeviceCommunicationHandler handler?.sendAndListenToDevice( - HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, + TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { data?.let { diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt index 5431804..0aaef49 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt @@ -25,6 +25,7 @@ import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.LanguageManager +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.testRight.UsbService import com.hoho.android.usbserial.driver.UsbSerialDriver @@ -185,9 +186,9 @@ class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler } } - override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) { - mService.sendAndListenToHemoCube( - command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, + override fun sendAndListenToDevice(command: TrueHemeCommands, listener: UsbServiceListener) { + mService.sendAndListenToTrueHeme( + command = TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND, listener ) } diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index 10d34eb..e7933d1 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -15,6 +15,7 @@ import androidx.lifecycle.MutableLiveData import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.presentation.UsbServiceListener @@ -166,8 +167,8 @@ class DeviceProvisionFragment : Fragment() { } private fun getDeviceId() { - (activity as DeviceProvisionActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, + (activity as DeviceProvisionActivity).mService.sendAndListenToTrueHeme( + TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) {} diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 172e9f4..ee592d9 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -1,24 +1,21 @@ package com.example.hpostesting.presentation.hemocube -import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.SharedPreferences +import android.graphics.Color import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast -import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.MutableLiveData import com.example.hpostesting.data.DataHolder -import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands -import com.example.hpostesting.data.constant.TestStatus -import com.example.hpostesting.data.model.TestState import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.presentation.UsbServiceListener @@ -27,169 +24,85 @@ import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.UIUtils import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase +import com.google.firebase.perf.ktx.performance import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding -import kotlin.math.abs import kotlin.math.log10 -@Suppress("MemberVisibilityCanBePrivate") class HemoCubeFragment : Fragment() { private lateinit var binding: FragmentHemoCubeReferenceBinding private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() private lateinit var sharedPreferences: SharedPreferences - private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() private var isOnline = false private var currentDeviceData: DeviceData? = null private var resultData: String = "" - private var currentResultData: String = "" private var isUsingExistingBuffer = false private var isTestOngoing = false private var startListening = MutableLiveData(false) - private var led1BufferForDevice = 0.0 - private var led2BufferForDevice = 0.0 - private var led3BufferForDevice = 0.0 - private var led4BufferForDevice = 0.0 - private var led1SampleForDevice = 0.0 - private var led2SampleForDevice = 0.0 - private var led3SampleForDevice = 0.0 - private var led4SampleForDevice = 0.0 - private var fittedAbs1 = 0.0 - private var fittedAbs2 = 0.0 - private var fittedAbs3 = 0.0 - private var fittedAbs4 = 0.0 - private var calculatedPredictedDenovixRatio = 0.0 - private var validationError = false - private var deviceHardwareId = "" - private var allErrorMessages = "" - private var testStatusCode = 0.0 - private var repeatReadingCount = 0 - private var readingsPerSample = Constants.READINGS_PER_SAMPLE - private var uploadedToCloud = false - private var uploadedToMolbio = false - lateinit var testState: TestState + val testingTrace = Firebase.performance.newTrace("testing_trace") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, ): View { binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false) sharedPreferences = - requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - - testState = TestState( - testDetails = DataHolder.selectedTest?.toHemoCubeTestData(), - ) - + requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initViews() - listenToHemoCube() - getDeviceInfo() observeViewModel() + checkAndStartProcess() } - @SuppressLint("SetTextI18n") private fun initViews() { binding.btnSubmit.setOnClickListener { - binding.btnSubmit.isEnabled = false - binding.btnSubmit.isClickable = false activity?.runOnUiThread { binding.progressBar.visibility = View.VISIBLE - binding.btnSubmit.visibility = View.GONE } hemoCubeViewModel.uploadHemoCubeResultToDatabase( isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") ) } + if (isTestOngoing) { +// binding.btnKit.visibility = View.GONE +// binding.btnKit.isEnabled = false +// binding.btnKit.isClickable = false + } binding.tvTitle2.visibility = View.GONE binding.etAbhaId.visibility = View.GONE binding.nameEditText.visibility = View.GONE binding.tvTitle.visibility = View.GONE binding.btnGo.visibility = View.GONE - binding.btnPlacebuffer.visibility = View.GONE + binding.btnSubmit.isEnabled = false + binding.btnSubmit.isClickable = false + binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" - binding.tvSubtitle4.text = "Config" - - binding.btnSamplestart.setOnClickListener { - activity?.runOnUiThread { - binding.tvSubtitle4.visibility = View.VISIBLE -// binding.tvSubtitle4.text = "Sample Started" - } - startSampleProcess() - it.visibility = View.GONE - } - - binding.btnPlacebuffer.setOnClickListener { - if (isBufferValueAvailable() || !Constants.BLANK_EVERY_TEST) { - showBufferAlertDialog() - } else { - activity?.runOnUiThread { - binding.tvSubtitle4.visibility = View.VISIBLE -// binding.tvSubtitle4.text = "Buffer Started" - } - - checkAndStartProcess() - it.visibility = View.GONE - } - } - - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - activity?.runOnUiThread { - binding.tvDeviceMessages.visibility = View.VISIBLE - } - } + Log.e("nametext", binding.tvName.text.toString()) } private fun observeViewModel() { hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> if (result == "Success") { - uploadedToCloud = true - showToast(R.string.test_upload) - if (Constants.MOLBIO_INTEGRATION) { - hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { - when (it) { - is Result.Success -> { - uploadedToMolbio = true - it.data.data?.get(0)?.rawData?.let { it1 -> - hemoCubeViewModel.updateMolbioFlag( - it1._id - ) - } - handleReadingFinish() - } - - is Result.Error -> { - binding.btnSubmit.visibility = View.VISIBLE - //Remove this line of code while deploying to IOCL - it.exception.let { message -> - Toast.makeText( - activity, - "An error occurred: $message", - Toast.LENGTH_LONG - ) - .show() - } - handleReadingFinish() - } - - else -> {} - } - } - } else { - handleReadingFinish() - } + showToast("Test Results Uploaded Successfully") + val i = Intent( + requireContext().applicationContext, DashboardActivity::class.java + ) + startActivity(i) + (activity as HemocubeActivity).finish() } if (result == "Local") { - showToast(R.string.internt_not_local) + showToast("Internet not available, test details stored locally") startActivity(Intent(requireActivity(), DashboardActivity::class.java)) } if (result == "Error") { - showToast(R.string.error_local) + showToast("Error uploading data, test details stored locally") startActivity(Intent(requireActivity(), DashboardActivity::class.java)) } @@ -206,9 +119,9 @@ class HemoCubeFragment : Fragment() { apply { DataHolder.hemoCubeTestData?.let { currentDeviceData?.coefficients?.let { coefficients -> -// val coefficient1 = coefficients[0] -// val coefficient2 = coefficients[1] -// val result = coefficient1 * coefficient2 + val coefficient1 = coefficients[0] + val coefficient2 = coefficients[1] + val result = coefficient1 * coefficient2 } } isOnline = isNetworkAvailable @@ -218,84 +131,51 @@ class HemoCubeFragment : Fragment() { hemoCubeViewModel.messages.observe(viewLifecycleOwner) { binding.tvSubtitle4.text = it } - - hemoCubeViewModel.deviceMessages.observe(viewLifecycleOwner) { - binding.tvDeviceMessages.text = it - } - } - - private fun handleReadingFinish() { - if (allReadingsComplete(repeatReadingCount, readingsPerSample) && uploadedToCloud) { - if (validationError) { - hemoCubeViewModel.messages.postValue("Error") - return - } - activity?.runOnUiThread { - binding.btnSubmit.visibility = View.GONE - val i = Intent( - requireContext().applicationContext, DashboardActivity::class.java - ) - startActivity(i) - } - } else { - hemoCubeViewModel.messages.postValue("Reading $repeatReadingCount completed") - resetTest() - startSampleProcess() - } - } - - fun allReadingsComplete(repeatReadingCount: Int, readingsPerSample: Int): Boolean { - return repeatReadingCount >= readingsPerSample - } - - private fun resetTest() { - testStatusCode = 0.0 - allErrorMessages = "" - validationError = false - resultData = "" - currentResultData = "" +// startListening.observe(viewLifecycleOwner) { +// if (it) { +// lifecycleScope.launch { +// delay(1000) +// if (binding.tvSubtitle4.text.toString().isEmpty()) { +// (activity as HemocubeActivity).reconnectDevice() +// if (isBufferValueAvailable()) { +// showBufferAlertDialog() +// } else { +// listenToHemoCube() +// startBufferProcess() +// } +// } +// } +// } +// } } private fun checkAndStartProcess() { - startBufferProcess() + if (isBufferValueAvailable()) { + showBufferAlertDialog() + } else { + listenToHemoCube() + startBufferProcess() + } } private fun isBufferValueAvailable(): Boolean { - return try { - if (sharedPreferences.getString( - Constants.BUFFER_VALUE_1, "" - ) != "" && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "") != "" - && sharedPreferences.getString(Constants.BUFFER_VALUE_3, "") != "" - && sharedPreferences.getString(Constants.BUFFER_VALUE_4, "") != "" - ) { - sharedPreferences.getString(Constants.BUFFER_VALUE_1, "") - ?.toDouble()!! > 0.0 && sharedPreferences.getString( - Constants.BUFFER_VALUE_2, - "" - ) - ?.toDouble()!! > 0.0 && sharedPreferences.getString( - Constants.BUFFER_VALUE_3, - "" - ) - ?.toDouble()!! > 0.0 && sharedPreferences.getString( - Constants.BUFFER_VALUE_4, - "" - ) - ?.toDouble()!! > 0.0 - } else { - false - } - } catch (e: Exception) { - showToast(R.string.error_exist) + return if (sharedPreferences.getString( + Constants.BUFFER_VALUE_1, "" + ) != "" && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "") != "" + ) { + sharedPreferences.getString(Constants.BUFFER_VALUE_1, "") + ?.toDouble()!! > 0.0 && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "") + ?.toDouble()!! > 0.0 + } else { false } } private fun showBufferAlertDialog() { val title = "WARNING" - val message = getString(R.string.do_exist) + val message = "Do you want to continue with existing buffer?" val negativeText = getString(R.string.no) - val positiveText = getString(R.string.yes) + val positiveText = "Yes" UIUtils.createAlertDialog(requireContext(), title, @@ -304,22 +184,23 @@ class HemoCubeFragment : Fragment() { positiveText, object : MyDialogListener { override fun onClickNegativeButton() { + listenToHemoCube() startBufferProcess() } override fun onClickPositiveButton() { - activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.GONE - binding.btnSamplestart.visibility = View.VISIBLE - binding.tvSubtitle4.text = getString(R.string.place_sample) - } + listenToHemoCube() + startSampleProcess() isUsingExistingBuffer = true } }) } private fun listenToHemoCube() { - DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData() + if (DataHolder.hemoCubeTestData == null) { + DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData() + } + hemoCubeViewModel.progressBar.postValue(true) val fullReadOutput = StringBuilder() @@ -331,7 +212,7 @@ class HemoCubeFragment : Fragment() { data?.let { val stringData = String(it) fullReadOutput.append(stringData) - handleUsbData(stringData) + handleUsbData(stringData, fullReadOutput) } } @@ -340,807 +221,223 @@ class HemoCubeFragment : Fragment() { } }) } catch (e: Exception) { - showToast(R.string.test_ongoing) + showToast("test is going on") Firebase.crashlytics.recordException(e) } } - private fun getDeviceInfo() { - hemoCubeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - data?.let { - val stringData = String(it) - hemoCubeViewModel.messages.postValue(stringData) - binding.tvSubtitle4.text = stringData - } - } - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - private fun loadDACValues() { - hemoCubeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.LOAD_DAC_VALUES, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - fun handleUsbData(stringData: String) { + private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) { if (stringData.contains("#")) { + hemoCubeViewModel.messages.postValue(stringData) isTestOngoing = true } resultData += stringData - currentResultData += stringData - hemoCubeViewModel.deviceMessages.postValue(currentResultData) when { - resultData.contains("SNE") && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { - processV2HardwareId(resultData) - loadDACValues() - } - - (resultData.contains("SN") && !resultData.contains("SNS") && !resultData.contains("SNE") && resultData.length >= 15) && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { - processV1HardwareId(resultData) - } - - (resultData.contains("#LS") && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_STARTED.code) -> { - // air reading 1 - this.testStatusCode = TestStatus.FIRST_EMPTY_AIR_READING_STARTED.code - hemoCubeViewModel.messages.postValue("Air reading started") - } - - (resultData.contains("#LC") && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code) -> { - // air reading 1, send command to print - this.testStatusCode = TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code - hemoCubeViewModel.messages.postValue("Air reading completed") + stringData.contains("#Buffer Completed") -> showStartSampleDialog() + stringData.contains("#Sample Completed") -> { fetchResult() + testingTrace.stop() } - (resultData.contains("#RC") && this.testStatusCode < TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code) -> { - this.testStatusCode = TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code - hemoCubeViewModel.messages.postValue("EPROM ADC Loaded") - showStartBufferButton() - } - - resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> { - hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started)) - this.testStatusCode = TestStatus.BUFFER_STARTED.code - } - - resultData.contains("#BC") && this.testStatusCode < TestStatus.BUFFER_COMPLETED.code -> { - this.testStatusCode = TestStatus.BUFFER_COMPLETED.code - activity?.runOnUiThread { - binding.tvSubtitle4.text = getString(R.string.buffer_completed) - binding.btnSamplestart.visibility = View.VISIBLE + stringData.contains("RESULT") || resultData.contains("REND") -> { + var validString: String + val results: List + if (stringData.contains("RESULT")) { + validString = isValidResult(stringData) + if (validString.isEmpty()) { + results = resultData.split("\n") + validString = parseResult(results) + } + } else { + results = resultData.split("\n") + validString = parseResult(results) } - } - - (resultData.contains("#SS") || resultData.contains("#SS1")) && this.testStatusCode < TestStatus.SAMPLE_STARTED.code -> { - this.testStatusCode = TestStatus.SAMPLE_STARTED.code - activity?.runOnUiThread { - binding.tvSubtitle4.text = getString(R.string.sample_started) - binding.btnSamplestart.visibility = View.GONE + if (validString.isNotEmpty()) { + handleValidResult(validString, resultData) } } - - (resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> { - this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code - hemoCubeViewModel.messages.postValue( - getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data) - ) - fetchResult() - currentResultData = "" - } - - resultData.contains("ovf") -> { - hemoCubeViewModel.messages.postValue( - getString(R.string.power_bank) - ) - } - - currentResultData.contains("#SS2") && this.testStatusCode < TestStatus.FIRST_GAIN_STARTED.code -> { - this.testStatusCode = TestStatus.FIRST_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("1.3X Gain Started") - } - - currentResultData.contains("#SC2") && this.testStatusCode < TestStatus.FIRST_GAIN_COMPLETED.code -> { - this.testStatusCode = TestStatus.FIRST_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("1.3X Gain Completed") - fetchResult() - } - - currentResultData.contains("#SS3") && this.testStatusCode < TestStatus.SECOND_GAIN_STARTED.code -> { - this.testStatusCode = TestStatus.SECOND_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("2X Gain Started") - } - - currentResultData.contains("#SC3") && this.testStatusCode < TestStatus.SECOND_GAIN_COMPLETED.code -> { - this.testStatusCode = TestStatus.SECOND_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("2X Gain Completed") - fetchResult() - } - - currentResultData.contains("#SS5") && this.testStatusCode < TestStatus.FORTH_GAIN_STARTED.code -> { - this.testStatusCode = TestStatus.FORTH_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("7.6X Gain Started") - } - - currentResultData.contains("#SC5") && this.testStatusCode < TestStatus.FORTH_GAIN_COMPLETED.code -> { - this.testStatusCode = TestStatus.FORTH_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("7.6X Gain Completed") - fetchResult() - } - - (resultData.contains("#LS") && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_READING_STARTED.code) -> { - // air reading 2 - this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_READING_STARTED.code - hemoCubeViewModel.messages.postValue("Air reading started") - } - - (resultData.contains("#LC") && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code) -> { - // air reading 2, print values - this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code - hemoCubeViewModel.messages.postValue("Air reading completed") - fetchResult() - } - - resultData.contains("REND") && this.testStatusCode < TestStatus.SAMPLE_PRINT_COMPLETED.code -> { - handleSampleCompleted() - } - - currentResultData.contains("REND") - && this.testStatusCode >= TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code - && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_PRINT_COMPLETED.code -> { - this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("First air reading completed") - - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { - led1Air1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2Air1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3Air1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Air1 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - } - - startBufferProcess() - currentResultData = "" - } - - currentResultData.contains("REND") - && this.testStatusCode >= TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code - && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_PRINT_COMPLETED.code -> { - this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("Second air reading completed") - - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { - led1Air2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2Air2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3Air2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Air2 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - } - - sendSecondGainCommand() - currentResultData = "" - } - - currentResultData.contains("REND") - && this.testStatusCode >= TestStatus.FIRST_GAIN_COMPLETED.code - && this.testStatusCode < TestStatus.FIRST_GAIN_PRINT_COMPLETED.code -> { - this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("1.3X gain data gathered") - - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { - led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Gain1 = - resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - } - - sendSecondGainCommand() - currentResultData = "" - } - - currentResultData.contains("REND") - && this.testStatusCode >= TestStatus.FIRST_GAIN_PRINT_COMPLETED.code - && this.testStatusCode < TestStatus.SECOND_GAIN_PRINT_COMPLETED.code -> { - this.testStatusCode = TestStatus.SECOND_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("2X gain data gathered") - - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { - led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Gain2 = - resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - } - - sendForthGainCommand() - currentResultData = "" - } - - currentResultData.contains("REND") - && this.testStatusCode >= TestStatus.SECOND_GAIN_PRINT_COMPLETED.code - && this.testStatusCode < TestStatus.FORTH_GAIN_PRINT_COMPLETED.code -> { - this.testStatusCode = TestStatus.FORTH_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("7.6X gain data gathered") - - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { - led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Gain4 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - } - - finishReading() - } } } - fun finishReading() { - repeatReadingCount += 1 - isTestOngoing = false - if (readingsPerSample == 1) { - activity?.runOnUiThread { - binding.btnSubmit.visibility = View.VISIBLE - binding.btnSubmit.isEnabled = true - binding.btnSubmit.isClickable = true -// binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) - binding.ivCheck.visibility = View.VISIBLE - } - } else { - hemoCubeViewModel.uploadHemoCubeResultToDatabase( - isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") - ) - } - } - - fun handleSampleCompleted() { - - this.testStatusCode = TestStatus.SAMPLE_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue( - getString(R.string.data_collected_processing_data) - ) - - val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) - var bufferIntensity = resultLines[1].split(' ')[1].trim() - led1BufferForDevice = if (isUsingExistingBuffer) { - sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()!! - } else { - bufferIntensity.toDoubleOrNull()!! - } - bufferIntensity = resultLines[2].split(' ')[1].trim() - led2BufferForDevice = if (isUsingExistingBuffer) { - sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull()!! - } else { - bufferIntensity.toDoubleOrNull()!! - } - bufferIntensity = resultLines[3].split(' ')[1].trim() - led3BufferForDevice = if (isUsingExistingBuffer) { - sharedPreferences.getString(Constants.BUFFER_VALUE_3, "")?.toDoubleOrNull()!! - } else { - bufferIntensity.toDoubleOrNull()!! - } - bufferIntensity = resultLines[4].split(' ')[1].trim() - led4BufferForDevice = if (isUsingExistingBuffer) { - sharedPreferences.getString(Constants.BUFFER_VALUE_4, "")?.toDoubleOrNull()!! - } else { - bufferIntensity.toDoubleOrNull()!! - } - - led1SampleForDevice = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! - led2SampleForDevice = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! - led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4SampleForDevice = - resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! - processResult() - if (Constants.PQ_MODE) { - finishReading() - } else { - sendFirstGainCommand() - } - currentResultData = "" - } - - fun processV1HardwareId(resultData: String) { - val hardwareId = extractV1HardwareId(resultData) - - if (!hardwareId.isNullOrBlank()) { - updateDeviceId(hardwareId) - } else { - hemoCubeViewModel.messages.postValue("Config error") - } - - if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) { - assignDefaultDevice(resultData) -// testState.allErrorMessages += "Calibration configuration for this device id is not found\n" - } - if (!Constants.BUFFER_INTENSITY_THRESHOLDS.containsKey(deviceHardwareId)) { -// testState.allErrorMessages += "ADC thresholds for this device id are not found\n" - } - } - - fun showStartBufferButton() { + private fun showError() { activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.VISIBLE - } - hemoCubeViewModel.messages.postValue(getString(R.string.start)) - } + UIUtils.createAlertDialog(requireContext(), + "Device Error", + "Something is wrong with the device, please disconnect and reconnect the device and test the user again", + getString(R.string.noo), + "Yes", + object : MyDialogListener { + override fun onClickNegativeButton() {} - fun extractV1HardwareId(input: String): String? { - val regex = Regex("SN (\\S+)") - val matchResult = regex.find(input) - - return matchResult?.groupValues?.get(1) - } - - fun processV2HardwareId(resultData: String) { - val hardwareId = extractV2HardwareId(resultData) - - if (!hardwareId.isNullOrBlank()) { - updateDeviceId(hardwareId) -// activity?.runOnUiThread { -// binding.btnPlacebuffer.visibility = View.VISIBLE -// } -// hemoCubeViewModel.messages.postValue(getString(R.string.start)) - } else { - hemoCubeViewModel.messages.postValue("Config error") - } - - if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) { - assignDefaultDevice(resultData) - testState.allErrorMessages += "Calibration configuration for this device id is not found\n" - } - if (!Constants.BUFFER_INTENSITY_THRESHOLDS.containsKey(deviceHardwareId)) { - testState.allErrorMessages += "ADC thresholds for this device id are not found\n" - } - } - - fun assignDefaultDevice(configData: String) { - deviceHardwareId = "HCV-000-3001" - testStatusCode = TestStatus.CONFIG_COMPLETED.code -// activity?.runOnUiThread { -// binding.btnPlacebuffer.visibility = View.VISIBLE -// } -// hemoCubeViewModel.messages.postValue(getString(R.string.start)) - } - - fun extractV2HardwareId(input: String): String? { - val pattern = Regex("SNS\\s*(.*?)\\s*SNE") - val matchResult: MatchResult? = pattern.find(input) - - return matchResult?.groups?.get(1)?.value - } - - fun updateDeviceId(hardwareId: String?) { - hardwareId?.let { - deviceHardwareId += it - with(sharedPreferences.edit()) { - putString(Constants.DEVICE_ID, deviceHardwareId) - apply() - } - testStatusCode = TestStatus.CONFIG_COMPLETED.code + override fun onClickPositiveButton() { + startActivity(Intent(requireActivity(), DashboardActivity::class.java)) + } + }) } } fun handleBackButtonPress() { if (isTestOngoing) { - showToast(R.string.test_go_noback) + // If the test is ongoing, don't allow the back button action + // You can optionally show a message to the user indicating why the back button is disabled + // For example, show a Toast or Snackbar. + showToast("Test is ongoing. Cannot go back.") } else { + // If the test is not ongoing, you can trigger the back action of the hosting activity activity?.onBackPressed() } } - private fun processResult() { + private fun showStartSampleDialog() { + activity?.runOnUiThread { + UIUtils.createAlertDialog(requireContext(), + "Start Sample", + "Do you want to start sample reading?", + getString(R.string.no), + "Yes", + object : MyDialogListener { + override fun onClickNegativeButton() {} + + override fun onClickPositiveButton() { + listenToHemoCube() + startSampleProcess() + } + }) + } + } + + private fun handleValidResult(validString: String, fullReadOutput: String) { try { - hemoCubeViewModel.messages.postValue(getString(R.string.processing_result)) + val result = validString.split(" ") val deviceLog = resultData - - val pInfo = requireActivity().packageManager.getPackageInfo( - requireActivity().packageName, 0 - ) - val version = pInfo.versionName - - val led1Average = log10(led1BufferForDevice.div(led1SampleForDevice)) - val led2Average = log10(led2BufferForDevice.div(led2SampleForDevice)) - val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice)) - val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice)) - val deviceRatio = led2Average / led1Average - val borderlineMetric = (led1Average - led2Average) / deviceRatio - - if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) - ?.get(0)!! - || led2BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 1 - )?.get(0)!! - || led3BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 2 - )?.get(0)!! - || led4BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 3 - )?.get(0)!! - ) { -// validationError = true -// testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)" - activity?.runOnUiThread { -// binding.errorMessage.text = getString(R.string.error_improper_buffer_low) -// binding.errorMessage.visibility = View.VISIBLE - } - } - - if (led1BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) - ?.get(1)!! - || led2BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 1 - )?.get(1)!! - || led3BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 2 - )?.get(1)!! - || led4BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get( - 3 - )?.get(1)!! - ) { -// validationError = true -// testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n" - activity?.runOnUiThread { -// binding.errorMessage.text = - getString(R.string.error_improper_buffer_high) -// binding.errorMessage.visibility = View.VISIBLE - } - } - - var gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(0) - var constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1) - fittedAbs1 = gradient?.times(led1Average)?.plus(constant!!)!! - - gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(0) - constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(1) - fittedAbs2 = gradient?.times(led2Average)?.plus(constant!!)!! - - gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(0) - constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(1) - fittedAbs3 = gradient?.times(led3Average)?.plus(constant!!)!! - - gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(0) - constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1) - fittedAbs4 = gradient?.times(led4Average)?.plus(constant!!)!! - - val slope1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(0) - val intercept1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(1) - val calculatedHb1 = (led1Average - intercept1!!) / slope1!! - - val slope2 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(0) - val intercept = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(1) - val calculatedHb2 = (led2Average - intercept!!) / slope2!! - - val slope3 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(2)?.get(0) - val intercept3 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(2)?.get(1) - val calculatedHb3 = (led3Average - intercept3!!) / slope3!! - - val slope4 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(0) - val intercept4 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(1) - val calculatedHb4 = (led4Average - intercept4!!) / slope4!! - - calculatedPredictedDenovixRatio = fittedAbs3.div(fittedAbs1) - - val slope = (led4Average - led1Average) / (431 - 411) - val calculatedSlopeRatio = abs(led2Average / slope) - val slopeClass = slopeRatioClassification(calculatedSlopeRatio) - - if (fittedAbs1 <= fittedAbs2) { -// validationError = true -// testState.allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n" - activity?.runOnUiThread { -// binding.errorMessage.text = getString(R.string.error_invalid_test) -// binding.errorMessage.visibility = View.VISIBLE - } - } - - if (fittedAbs1 < 0 || fittedAbs2 < 0 || fittedAbs3 < 0 || fittedAbs4 < 0) { -// validationError = true - activity?.runOnUiThread { - binding.errorMessage.text = getString(R.string.error_negative_abs) -// binding.errorMessage.visibility = View.VISIBLE - } - } - - val absorbanceLowerLimit = 0.0 - if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) { - validationError = true - activity?.runOnUiThread { - binding.errorMessage.text = "Invalid" - binding.errorMessage.visibility = View.VISIBLE - } - } - - if (fittedAbs3 < 0.1) { -// validationError = true -// testState.allErrorMessages += "Error: Low Hb. Repeat test" + "\n" - activity?.runOnUiThread { -// binding.errorMessage.text = "Error: Low Hb. Repeat test" -// binding.errorMessage.visibility = View.VISIBLE - } - } - - DataHolder.hemoCubeTestData?.apply { - deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString() - led1Buffer = led1BufferForDevice - led2Buffer = led2BufferForDevice - led3Buffer = led3BufferForDevice - led4Buffer = led4BufferForDevice - appVersion = version - this.led1Sample = led1SampleForDevice - this.led2Sample = led2SampleForDevice - this.led3Sample = led3SampleForDevice - this.led4Sample = led4SampleForDevice - this.led1Average = led1Average - this.led2Average = led2Average - this.led3Average = led3Average - this.led4Average = led4Average - this.abs1 = fittedAbs1 - this.abs2 = fittedAbs2 - this.abs3 = fittedAbs3 - this.abs4 = fittedAbs4 - this.hb3 = calculatedHb3 - this.hb4 = calculatedHb4 - this.deviceRatio = deviceRatio - this.calculatedRatio = calculateRatio(deviceRatio) - this.predictedDenovixRatio = calculatedPredictedDenovixRatio - this.slopeRatio = calculatedSlopeRatio - this.coefficients = currentDeviceData?.coefficients?.get(0) - .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() - this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) - this.deviceRatioClass = deviceRatioClassification(deviceRatio) - this.borderlineMethod2Class = reclassifyWithBorderlineMethod2(deviceRatio, deviceRatioBorderlineThresholds(deviceRatio), led2Average) - this.slopeRatioClass = slopeClass - this.classificationResult = findResultWithAdditionalMethods( - deviceRatio, - deviceRatioClass, - borderlineMetric - ) - hemoCubeViewModel.messages.postValue( - "${this.classificationResult} \n Device Ratio: ${ - "%.3f".format( - this.deviceRatio - ) - }" - ) - if (DataHolder.hemoCubeTestData?.testType == "HB") - hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4") - this.errorMessages = testState.allErrorMessages - this.resultData = deviceLog - this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString() - this.batteryCapacity = - hemoCubeViewModel.getBatteryCapacity(requireContext()).toString() - this.batteryMaxCapacity = - hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString() - this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString() - this.batteryVoltage = - hemoCubeViewModel.getBatteryVoltage(requireContext()).toString() - } - - if (!isUsingExistingBuffer) { + if (result.size == 8) { + val deviceSerialNo = result[2] with(sharedPreferences.edit()) { - putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString()) + putString(Constants.DEVICE_ID, deviceSerialNo) apply() } + val loginId = sharedPreferences.getString(Constants.USER_ID, "").toString() + if (checkDeviceIdMismatch(deviceSerialNo, loginId)) { + activity?.runOnUiThread { + binding.errorMessage.text = "Warning: Login Id is different" + binding.errorMessage.visibility = View.VISIBLE + } + } + val led1BufferForDevice = if (isUsingExistingBuffer) { + sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull() + } else { + result[3].toDoubleOrNull() + } + val led2BufferForDevice = if (isUsingExistingBuffer) { + sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull() + } else { + result[4].toDoubleOrNull() + } + val pInfo = requireActivity().packageManager.getPackageInfo( + requireActivity().packageName, 0 + ) + val version = pInfo.versionName + val led1Sample = result[5].toDoubleOrNull() + val led2Sample = result[6].toDoubleOrNull() + val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0) + val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0) + val deviceRatio = led1Average / led2Average +// if (led1BufferForDevice!! > 20000 && led1BufferForDevice < 24000 && led2BufferForDevice!! > 20000 && led2BufferForDevice < 24000) { +// if (led1Sample!! < led1BufferForDevice && led1Sample < 24000 && led2Sample!! < led2BufferForDevice && led2Sample < 24000) { +// if (deviceRatio < 0.08) { +// if (deviceRatio > 1.07) { +// +// } +// } +// } +// } + + if (led1Average < 0 || led2Average < 0) { + activity?.runOnUiThread{ + binding.errorMessage.text = "Warning: Negative Abs. Retake Blank Reading" + binding.errorMessage.visibility = View.VISIBLE + } + } + + DataHolder.hemoCubeTestData?.apply { + deviceId = deviceSerialNo + led1Buffer = led1BufferForDevice + led2Buffer = led2BufferForDevice + appVersion = version + this.led1Sample = led1Sample + this.led2Sample = led2Sample + this.led1Average = led1Average + this.led2Average = led2Average + this.deviceRatio = deviceRatio + this.calculatedRatio = calculateRatio(deviceRatio) + this.coefficients = currentDeviceData?.coefficients?.get(0).toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() + this.classificationResult = findResult(calculatedRatio) + hemoCubeViewModel.messages.postValue(this.classificationResult) + this.resultData = deviceLog + if (!isUsingExistingBuffer) { + with(sharedPreferences.edit()) { + putString(Constants.BUFFER_VALUE_1, led1Buffer.toString()) + putString(Constants.BUFFER_VALUE_2, led2Buffer.toString()) + apply() + } + } + activity?.runOnUiThread { + binding.btnSubmit.visibility = View.VISIBLE + binding.btnSubmit.isEnabled = true + binding.btnSubmit.isClickable = true + binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) + } + } } } catch (e: Exception) { Toast.makeText( requireContext(), - R.string.error_processing_device_data, + "Error while processing device data", Toast.LENGTH_SHORT ).show() Firebase.crashlytics.recordException(e) } } - fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String { + private fun findResult(calculatedRatio: Double?): String { try { - if (deviceRatio != null && led2Average != null) { - if (deviceRatioClass == "Negative Borderline") { - return if (led2Average >= 0.15) - "Borderline. Normal" - else - "Borderline. Sickle Cell Trait" - } - if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { - return if (led2Average >= 0.19) - "Borderline. Sickle Cell Trait" - else - "Borderline. Sickle Cell Disease" - } - } - } catch (e: Exception) { - handleException(e) - return "Error" - } - return deviceRatioClass.toString() - } - - fun findResultWithAdditionalMethods( - deviceRatio: Double?, - deviceRatioClass: String?, - borderlineMetric: Double?, - ): String { - try { -// hemoCubeViewModel.messages.postValue("post classification checks") - if (deviceRatio != null && borderlineMetric != null) { - if (deviceRatioClass == "Negative Borderline") { - return if (borderlineMetric >= 2.4) - "Borderline. Normal" - else - "Borderline. Sickle Cell Trait" - } - if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { - return if (borderlineMetric >= 1.34) - "Borderline. Sickle Cell Trait" - else - "Borderline. Sickle Cell Disease" - } - } - } catch (e: Exception) { - handleException(e) - return "Error" - } - return deviceRatioClass.toString() - } - - fun deviceRatioBorderlineThresholds(ratio: Double?): String { - try { - if (ratio != null) { - val roundedRatio = String.format("%.3f", ratio).toDouble() - if (roundedRatio >= 0.11 && roundedRatio < 0.237) { -// setSubtitleTextColor(R.color.green_2) + if (calculatedRatio != null) { + if (calculatedRatio < 0.05) + return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume" + if (calculatedRatio in 0.05..0.155) return "Normal" - } - if (roundedRatio in 0.237..0.242) - return "Negative Borderline" - if (roundedRatio in 0.242..0.318) + if (calculatedRatio in 0.155..0.175) + return "Negative Borderline. Repeat Test" + if (calculatedRatio in 0.175..0.22) return "Sickle Cell Trait" - if (roundedRatio >= 0.318 && roundedRatio < 0.356) + if (calculatedRatio in 0.22..0.25) return "Positive for Sickle Cell. HPLC for Confirmation" - if (roundedRatio in 0.356..0.7) + if (calculatedRatio in 0.25..0.35) return "Sickle Cell Disease" + if (calculatedRatio > 0.35) + return "Inconclusive. Repeat with test with lower volume of blood" } else { - return "Invalid" + return "NULL" } } catch (e: Exception) { - handleException(e) - return "Error" - } - return "Invalid" - } - - fun deviceRatioClassification(ratio: Double?): String { - try { - if (ratio != null) { - if (ratio in 0.16..0.23) { -// setSubtitleTextColor(R.color.green_2) - return "Normal" - } - if (ratio in 0.23..0.25) - return "Negative Borderline" - if (ratio in 0.25..0.31) - return "Sickle Cell Trait" - if (ratio in 0.31..0.36) - return "Positive for Sickle Cell. HPLC for Confirmation" - if (ratio in 0.36..0.7) - return "Sickle Cell Disease" - } else { - return "Invalid" - } - } catch (e: Exception) { - handleException(e) - return "Error" - } - return "Invalid" - } - - fun setSubtitleTextColor(colorResId: Int) { - activity?.runOnUiThread { - binding.tvSubtitle4.setTextColor(ContextCompat.getColor(requireContext(), colorResId)) - } - } - - fun handleException(e: Exception) { - showToast(R.string.error_classification) - Firebase.crashlytics.recordException(e) - } - - fun slopeRatioClassification(ratio: Double?): String { - try { - hemoCubeViewModel.messages.postValue("result classification") - if (ratio != null) { - if (ratio in 0.0..30.0) - return getString(R.string.normal) - if (ratio in 30.0..35.0) - return getString(R.string.negative_borderline) - if (ratio in 35.0..50.0) - return getString(R.string.sickle_cell_trait) - if (ratio in 50.0..60.0) - return getString(R.string.positive_for_sickle_cell) - if (ratio > 60.0) - return getString(R.string.sickle_cell_disease) - } else { - return getString(R.string.invalid) - } - } catch (e: Exception) { - showToast(R.string.error_classification) + showToast("error while performing classification") Firebase.crashlytics.recordException(e) - return getString(R.string.error) + return "ERROR" } - return getString(R.string.invalid) + return "NULL" } - private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { - try { - hemoCubeViewModel.messages.postValue("result classification") - if (predictedDenovixRatio != null) { - if (predictedDenovixRatio in 0.0..0.16) { -// activity?.runOnUiThread { -// binding.tvSubtitle4.setTextColor( -// ContextCompat.getColor( -// requireContext(), -// R.color.brightGreen -// ) -// ) -// } - return getString(R.string.normal) - } - if (predictedDenovixRatio in 0.16..0.165) - return getString(R.string.negative_borderline) - if (predictedDenovixRatio in 0.165..0.235) - return getString(R.string.sickle_cell_trait) - if (predictedDenovixRatio in 0.235..0.24) - return getString(R.string.positive_borderline) - if (predictedDenovixRatio in 0.24..1.0) - return getString(R.string.sickle_cell_disease) - } else { - return getString(R.string.invalid) - } - } catch (e: Exception) { - showToast(R.string.error_classification) - Firebase.crashlytics.recordException(e) - return getString(R.string.error) - } - return getString(R.string.invalid) - } - - private fun showToast(messageResId: Int) { - Toast.makeText(requireContext(), getString(messageResId), Toast.LENGTH_SHORT).show() + private fun showToast(message: String) { + Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() } private fun startBufferProcess() { hemoCubeViewModel.progressBar.postValue(true) - activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.GONE - } - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_BUFFER_COMMAND, + (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} @@ -1151,61 +448,10 @@ class HemoCubeFragment : Fragment() { } private fun startSampleProcess() { + testingTrace.start() hemoCubeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_SAMPLE, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - private fun sendFirstGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FIRST_GAIN_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - private fun sendSecondGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.SECOND_GAIN_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - private fun sendThirdGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.THIRD_GAIN_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } - - private fun sendForthGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FORTH_GAIN_COMMAND, + (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} @@ -1218,7 +464,7 @@ class HemoCubeFragment : Fragment() { private fun fetchResult() { hemoCubeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND, + (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} @@ -1233,4 +479,33 @@ class HemoCubeFragment : Fragment() { val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0 return coefficient1 * ratio + coefficient2 } + + private fun parseResult(frames: List): String { + val lines = mutableListOf() + for (frame in frames.reversed()) { + if (frame.contains("REND") || frame.contains("RESULT")) lines += frame + if (frame.contains("RESULT")) { + break + } + } + val line = lines.reversed().joinToString("").trim() + if (line.contains("RESULT") && line.split(" ").size == 8) { + return line + } + return "" + } + + private fun isValidResult(line: String): String { + return if (line.contains("RESULT") && line.split(" ").size == 8) { + line + } else { + "" + } + } + + private fun checkDeviceIdMismatch(deviceId: String, loginId: String): Boolean { + if (!deviceId.isNullOrEmpty() && !loginId.isNullOrEmpty() && deviceId.last() != loginId.last()) + return true + return false + } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index d50c442..1026cb1 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -1,248 +1,78 @@ package com.example.hpostesting.presentation.hemocube import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.os.BatteryManager +import android.content.SharedPreferences import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.PeriodicWorkRequestBuilder -import androidx.work.WorkManager -import com.example.hpostesting.data.CsvWriter import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.NetworkStatusLiveData -import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants -import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeDao -import com.example.hpostesting.data.datasource.LocalFileDataSource +import com.example.hpostesting.data.dao.TrueHemeDao import com.example.hpostesting.data.model.Response -import com.example.hpostesting.data.model.log.UploadLogsResponse -import com.example.hpostesting.data.model.login.LoginRequest -import com.example.hpostesting.data.model.login.LoginResponse -import com.example.hpostesting.data.model.molbioresult.MolbioV2Result -import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest -import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData -import com.example.hpostesting.data.model.updates.CheckUpdateRequest -import com.example.hpostesting.data.model.updates.CheckUpdateResponse -import com.example.hpostesting.data.model.updates.DeviceUpdateRequest -import com.example.hpostesting.data.repository.Repository -import com.example.hpostesting.domain.CheckUpdateWorker -import com.example.hpostesting.domain.LogFileManager +import com.example.hpostesting.data.repository.DatabaseRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.MultipartBody -import okhttp3.RequestBody.Companion.asRequestBody -import okhttp3.ResponseBody import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale -import java.util.concurrent.TimeUnit import javax.inject.Inject -@Suppress("MemberVisibilityCanBePrivate") @HiltViewModel class HemoCubeViewModel @Inject constructor( private val hemoCubeDao: HemoCubeDao, - private val hemoCubeBufferDao: HemoCubeBufferDao, - private val repository: Repository, - private val logFileManager: LogFileManager, - private val localFileDataSource: LocalFileDataSource, + private val trueHemeDao: TrueHemeDao, + private val repository: DatabaseRepository, context: Context, ) : ViewModel() { var isServiceConnected = false val progressBar = MutableLiveData(false) - private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() val messages = MutableLiveData() - private val sharedPreference = - context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - - private val workManager = WorkManager.getInstance(context) - -// init { -// startPeriodicCheckUpdate() -// } - - val loginResponse = MutableLiveData>() - - val resultUpload = MutableLiveData>() - - val checkUpdate = MutableLiveData>() - - val deviceUpdate = MutableLiveData>() - val downloadcertificate = MutableLiveData>() - - val uploadLogs = MutableLiveData?>() - + private val sharedPreference: SharedPreferences = + context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) private val _networkStatusLiveData = NetworkStatusLiveData(context) - val allUserData = hemoCubeDao.getAll() - val allPendingUserToUpload = MutableLiveData>() - val allKitTestData = hemoCubeBufferDao.getAll() + val allUserData = trueHemeDao.getAll() val deviceData = MutableLiveData() - - val networkStatusLiveData: LiveData get() = _networkStatusLiveData - val deviceMessages = MutableLiveData() val fireBaseUpload = MutableLiveData() val fireBaseBulkUpload = MutableLiveData() - - private val batteryStatus: Intent? = - IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> - context.registerReceiver(null, ifilter) - } - - fun uploadHemoCubeResultToDatabase( - isOnline: Boolean, testStatus: Boolean, kitSerial: String?, - ) = viewModelScope.launch { - if (kitSerial != null) { - testDetails?.kitSerial = kitSerial - } - testDetails?.testStatus = testStatus - - try { - if (isOnline) { - parseData() - addResultTestToDb() - } else { - parseData() - testDetails?.testTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - hemoCubeDao.insertAll(testDetails!!) - fireBaseUpload.postValue("Local") - } - } catch (e: Exception) { - Log.e("Testdb", "Upload failed: ${e.message}") - } - } - - fun login(loginRequest: LoginRequest) = viewModelScope.launch { - loginResponse.postValue(Result.Loading()) - repository.login(loginRequest).let { - loginResponse.postValue(it) - } - } - - fun uploadResult(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch { - resultUpload.postValue(Result.Loading()) - repository.uploadResults(molbioV2ResultRequest).let { - resultUpload.postValue(it) - } - } - - fun checkUpdate(checkUpdateRequest: CheckUpdateRequest) = viewModelScope.launch { - checkUpdate.postValue(Result.Loading()) - repository.checkUpdate(checkUpdateRequest).let { - checkUpdate.postValue(it) - } - } - - fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch { - deviceUpdate.postValue(Result.Loading()) - repository.deviceUpdate(deviceUpdateRequest).let { - deviceUpdate.postValue(it) - } - } - - fun downloadClientCertificate() = viewModelScope.launch { - downloadcertificate.postValue(Result.Loading()) - repository.downloadClientCertificate().let { - downloadcertificate.postValue(it) - } - } - - fun startPeriodicCheckUpdate() { - val periodicRequest = PeriodicWorkRequestBuilder( - repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES - ).build() - - workManager.enqueueUniquePeriodicWork( - "checkUpdateWorker", ExistingPeriodicWorkPolicy.KEEP, periodicRequest - ) - } - - fun uploadLogs() = viewModelScope.launch { - uploadLogs.postValue(Result.Loading()) - val logFile = logFileManager.createLogFile().let { file -> - val requestBody = file?.asRequestBody("multipart/form-data".toMediaTypeOrNull()) - val multipartFile = - requestBody?.let { MultipartBody.Part.createFormData("logFile", file?.name, it) } - multipartFile?.let { partFile -> - repository.uploadLogs(partFile).let { result -> - uploadLogs.postValue(result) - } - } - } - } - fun uploadPendingUser() = viewModelScope.launch { - allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(false)) - } - - fun uploadHemoCubeResultToDatabaseForBufferCheck( - isOnline: Boolean, - bufferCheckData: BufferCheckData, - ) = + fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) = viewModelScope.launch { - if (isOnline) { - try { - when (val response = - repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { - is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") - fireBaseUpload.postValue("Success") - bufferCheckData.localFlag = true - hemoCubeBufferDao.insertAll(bufferCheckData) - } + if (kitSerial != null) { + testDetails?.kitSerial = kitSerial + } + testDetails?.testStatus = testStatus - is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") - fireBaseUpload.postValue("Error") - bufferCheckData.localFlag = true - hemoCubeBufferDao.insertAll(bufferCheckData) - } - - else -> {} - } - } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") - fireBaseUpload.postValue("Error") + try { + if (isOnline) { + parseData() + addResultTestToDb() + } else { + parseData() + testDetails?.testTime = SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + ).format(Calendar.getInstance().time) + hemoCubeDao.insertAll(testDetails!!) + fireBaseUpload.postValue("Local") } - } else { - hemoCubeBufferDao.insertAll(bufferCheckData) - fireBaseUpload.postValue("Local") + } catch (e: Exception) { + Log.e("Testdb", "Upload failed: ${e.message}") } } - fun bulkAddResultKitTestToDb(bufferCheckData: BufferCheckData) { - viewModelScope.launch { - bufferCheckData.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - when (repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { - is Response.Success -> { - fireBaseBulkUpload.postValue("Success") - updateBufferLocalFlag(bufferCheckData._id) - } - else -> { - fireBaseBulkUpload.postValue("Error") - } - } - } - } fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) = viewModelScope.launch { @@ -253,7 +83,7 @@ class HemoCubeViewModel @Inject constructor( deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) }) } - fun parseData() { + private fun parseData() { testDetails?.deviceRatio = DataHolder.hemocubeResult testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() testDetails?.location = DataHolder.location @@ -267,44 +97,14 @@ class HemoCubeViewModel @Inject constructor( testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString() testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer - testDetails?.led3Buffer = DataHolder.hemoCubeTestData?.led3Buffer - testDetails?.led4Buffer = DataHolder.hemoCubeTestData?.led4Buffer testDetails?.led1Sample = DataHolder.hemoCubeTestData?.led1Sample testDetails?.led2Sample = DataHolder.hemoCubeTestData?.led2Sample - testDetails?.led3Sample = DataHolder.hemoCubeTestData?.led3Sample - testDetails?.led4Sample = DataHolder.hemoCubeTestData?.led4Sample testDetails?.led1Average = DataHolder.hemoCubeTestData?.led1Average testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average - testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average - testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average - testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 - testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 - testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 - testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio - testDetails?.slopeRatio = DataHolder.hemoCubeTestData?.slopeRatio - testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients - testDetails?.incubationTime = DataHolder.hemoCubeTestData?.incubationTime.toString() - testDetails?.name = DataHolder.hemoCubeTestData?.name.toString() - testDetails?.birthYear = DataHolder.hemoCubeTestData?.birthYear.toString() - testDetails?.userImageURL = DataHolder.hemoCubeTestData?.userImageURL.toString() testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! - testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() - testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString() - testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString() - testDetails?.borderlineMethod2Class = DataHolder.hemoCubeTestData?.borderlineMethod2Class.toString() - testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString() - testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() - testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() - testDetails?.batteryMaxCapacity = DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString() - testDetails?.batteryTemperature = DataHolder.hemoCubeTestData?.batteryTemperature.toString() - testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString() - testDetails?.quickCapture = DataHolder.hemoCubeTestData?.quickCapture!! - testDetails?.solution = DataHolder.hemoCubeTestData?.solution - testDetails?.concentration = DataHolder.hemoCubeTestData?.concentration - testDetails?.volume = DataHolder.hemoCubeTestData?.volume } private fun addResultTestToDb() { @@ -324,26 +124,6 @@ class HemoCubeViewModel @Inject constructor( Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Success") testDetails.localFlag = true - if (Constants.MOLBIO_INTEGRATION) { - uploadResult( - MolbioV2ResultRequest( - mutableListOf( - MolbioV2Result( - rawData = testDetails, - analysisId = testDetails._id, - analysisDate = testDetails.testTime, - analysisStatus = testDetails.classificationResult, - thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(), - interpretation = testDetails.classificationResult, - testId = testDetails._id, - testTime = testDetails.testTime, - collectionTime = testDetails.testTime, - expiryTime = testDetails.testTime, - ) - ) - ) - ) - } hemoCubeDao.insertAll(testDetails) } @@ -352,8 +132,29 @@ class HemoCubeViewModel @Inject constructor( fireBaseUpload.postValue("Error") hemoCubeDao.insertAll(testDetails) } + } + } catch (e: Exception) { + Log.e("Testdb", "Exception during data upload: ${e.message}") + fireBaseUpload.postValue("Error") + } + } + } - else -> {} + + private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { + viewModelScope.launch { + try { + + when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { + is Response.Success -> { + Log.i("Testdb", "Data uploaded to Firestore successfully") + fireBaseUpload.postValue("Success") + } + + is Response.Error -> { + Log.e("Testdb", "Error uploading data to Firestore: $response") + fireBaseUpload.postValue("Error") + } } } catch (e: Exception) { Log.e("Testdb", "Exception during data upload: ${e.message}") @@ -384,167 +185,7 @@ class HemoCubeViewModel @Inject constructor( hemoCubeDao.updateFieldById(id = userId, true) } - fun updateMolbioFlag(userId: String) = viewModelScope.launch { - hemoCubeDao.updateMolbioFlag(id = userId, true) - } - - fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { - hemoCubeDao.insertAll(userData) - } - fun deleteById(userId: String) = viewModelScope.launch { hemoCubeDao.deleteById(id = userId) } - - - private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { - viewModelScope.launch { - try { - - when (val response = - repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { - is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") - fireBaseUpload.postValue("Success") - } - - is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") - fireBaseUpload.postValue("Error") - } - - else -> {} - } - } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") - fireBaseUpload.postValue("Error") - } - } - } - - private fun updateBufferLocalFlag(bufferId: String) = - viewModelScope.launch { - hemoCubeBufferDao.updateFieldById(id = bufferId, true) - } - - fun getLocalUserDataForCsv(context: Context): Boolean { - val localUserDataLiveData: LiveData> = hemoCubeDao.getAll() - - // Observe the LiveData to get the actual data when available - localUserDataLiveData.observeForever { localUserData -> - localUserData?.let { - val csvData = mutableListOf>() - - it.forEach { userData -> - csvData.add( - arrayOf( - userData._id, - userData.name, - userData.bloodGroup, - userData.birthYear, - userData.classificationResult, - userData.testTime.toString(), - userData.userImageURL - ) - ) - } - - val csvWriter = CsvWriter(context) - csvWriter.writeCsv("userData.csv", csvData) - - // Remove the observer to avoid leaks - localUserDataLiveData.removeObserver {} - } - } - - return true // Assuming success, you might want to modify this based on your actual logic - } - - fun getBatteryLevel(): Float? { - val batteryPct: Float? = batteryStatus?.let { intent -> - val level: Int = - intent.getIntExtra( - BatteryManager.EXTRA_LEVEL, - -1 - ) - val scale: Int = - intent.getIntExtra( - BatteryManager.EXTRA_SCALE, - -1 - ) - level * 100 / scale.toFloat() - } - - return batteryPct - } - - fun getBatteryTemperature(): Float? { - val batteryTemp: Float? = batteryStatus?.let { intent -> - val temperature = intent.getIntExtra( - BatteryManager.EXTRA_TEMPERATURE, - 0 - ) - temperature.toFloat() / 10 - } - - return batteryTemp - } - - fun getBatteryVoltage(context: Context): Float { - val batteryIntent = - context.registerReceiver( - null, - IntentFilter(Intent.ACTION_BATTERY_CHANGED) - ) - val voltage = batteryIntent?.getIntExtra( - BatteryManager.EXTRA_VOLTAGE, - 0 - ) ?: 0 - - // milli-volts to volts - return voltage.toFloat() / 1000 - } - - - fun getBatteryCapacity(context: Context): Int { - val batteryManager = - context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager - val currentCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) - - return currentCapacity - } - - fun getBatteryMaxCapacity(context: Context): Float { - val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager - val designCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - val currentCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) - - // Calculate the estimated maximum battery capacity in mAh - val maxCapacity = currentCapacity.toFloat() / designCapacity.toFloat() * 100 - - return maxCapacity - } - - fun createCSV(hemoCubeTestData: List, appContext: Context) = - viewModelScope.launch { - val fileName = "HPOS${getCurrentDate()}.csv" - if (localFileDataSource.exportDataToCSV(fileName, hemoCubeTestData)) { - hemoCubeTestData.forEach { data -> - data.localFlag = true - hemoCubeDao.updateCSVFieldById( - data._id, - true - ) - } - } - } - - fun getCurrentDate(): String { - return SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt index 27c27ca..dde72de 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt @@ -1,6 +1,5 @@ package com.example.hpostesting.presentation.hemocube -import android.annotation.SuppressLint import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.ComponentName @@ -11,7 +10,6 @@ import android.content.ServiceConnection import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbManager -import android.os.Build import android.os.Bundle import android.os.IBinder import android.util.Log @@ -23,7 +21,6 @@ import androidx.core.content.ContextCompat import androidx.core.view.get import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.Constants -import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.presentation.testRight.UsbService import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialProber @@ -62,7 +59,6 @@ open class HemocubeActivity : AppCompatActivity() { } } - private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { val binder = service as UsbService.UsbServiceBinder @@ -77,12 +73,6 @@ open class HemocubeActivity : AppCompatActivity() { } } - override fun attachBaseContext(newBase: Context?) { - val languageCode = LanguageManager.getSavedLanguage(newBase!!) - LanguageManager.setLocale(newBase, languageCode) - super.attachBaseContext(newBase) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHemocubeBinding.inflate(layoutInflater) @@ -126,12 +116,12 @@ open class HemocubeActivity : AppCompatActivity() { } } - @SuppressLint("MutableImplicitPendingIntent") + private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { val mPendingIntent: PendingIntent if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { mPendingIntent = PendingIntent.getBroadcast( - this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE + this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE ) } else { mPendingIntent = PendingIntent.getBroadcast( @@ -143,11 +133,7 @@ open class HemocubeActivity : AppCompatActivity() { } val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - registerReceiver(broadcastReceiver, filter, RECEIVER_EXPORTED) - }else{ - registerReceiver(broadcastReceiver, filter) - } + registerReceiver(broadcastReceiver, filter) manager.requestPermission(device, mPendingIntent) } @@ -180,6 +166,7 @@ open class HemocubeActivity : AppCompatActivity() { } } + fun onErrorReported(msg: String) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() if (!isFinishing) onBackPressed() diff --git a/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt index 16cf5d5..53045f8 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt @@ -9,6 +9,7 @@ import android.util.Log import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.TestRightCommands +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.presentation.UsbServiceListener import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialPort @@ -100,7 +101,14 @@ class UsbService : Service() { listener.onUsbError(e) } } + fun listenToTrueHeme(listener: UsbServiceListener) { + this.listener = listener + try { + } catch (e: IOException) { + listener.onUsbError(e) + } + } fun sendAndListenToHemoCube(command: HemoCubeCommands, listener: UsbServiceListener) { try { this.bus = listener @@ -109,4 +117,12 @@ class UsbService : Service() { listener.onUsbError(e) } } + fun sendAndListenToTrueHeme(command: TrueHemeCommands, listener: UsbServiceListener) { + try { + this.bus = listener + mPort.write(command.command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS) + } catch (e: IOException) { + listener.onUsbError(e) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeActivity.kt index f9222a5..0928a74 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeActivity.kt @@ -11,6 +11,7 @@ import android.content.ServiceConnection import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbManager +import android.os.Build import android.os.Bundle import android.os.IBinder import android.util.Log @@ -23,26 +24,24 @@ import androidx.core.view.get import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.LanguageManager -import com.example.hpostesting.presentation.hemocube.HemoCubeFragment -import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.testRight.UsbService import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialProber import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R -import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding +import `in`.sminnovations.hpostesting.databinding.ActivityTruehemeBinding @AndroidEntryPoint -class TrueHemeActivity : AppCompatActivity() { - private lateinit var binding: ActivityHemocubeBinding - private val viewModel by viewModels() +open class TrueHemeActivity : AppCompatActivity() { + private lateinit var binding: ActivityTruehemeBinding + private val viewModel by viewModels() private var myMenu: Menu? = null private lateinit var mDriver: UsbSerialDriver private var mConnection: UsbDeviceConnection? = null lateinit var mService: UsbService - private val TAG = "HemoCube" + private val TAG = "TrueHeme" private val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -63,6 +62,7 @@ class TrueHemeActivity : AppCompatActivity() { } } + private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { val binder = service as UsbService.UsbServiceBinder @@ -83,10 +83,9 @@ class TrueHemeActivity : AppCompatActivity() { super.attachBaseContext(newBase) } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivityHemocubeBinding.inflate(layoutInflater) + binding = ActivityTruehemeBinding.inflate(layoutInflater) setContentView(binding.root) setSupportActionBar(binding.myToolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) @@ -96,7 +95,7 @@ class TrueHemeActivity : AppCompatActivity() { private fun setupListener() { DataHolder.usbConnected.observe(this) { - Log.d("USB OBSERVE", "HemoCube called -> $it") + Log.d("USB OBSERVE", "TrueHeme called -> $it") if (it) { myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24) @@ -127,25 +126,28 @@ class TrueHemeActivity : AppCompatActivity() { } } - - @SuppressLint("MutableImplicitPendingIntent", "UnspecifiedRegisterReceiverFlag") + @SuppressLint("MutableImplicitPendingIntent") private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { val mPendingIntent: PendingIntent if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { mPendingIntent = PendingIntent.getBroadcast( - this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE + this, 0, Intent(Constants.TRUEHEME_USB_PERMISSION), PendingIntent.FLAG_MUTABLE ) } else { mPendingIntent = PendingIntent.getBroadcast( this, 0, - Intent(Constants.HEMOCUBE_USB_PERMISSION), + Intent(Constants.TRUEHEME_USB_PERMISSION), PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE ) } - val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) - registerReceiver(broadcastReceiver, filter) + val filter = IntentFilter(Constants.TRUEHEME_USB_PERMISSION) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + registerReceiver(broadcastReceiver, filter, RECEIVER_EXPORTED) + }else{ + registerReceiver(broadcastReceiver, filter) + } manager.requestPermission(device, mPendingIntent) } @@ -164,21 +166,20 @@ class TrueHemeActivity : AppCompatActivity() { private fun moveToNext() { if (supportFragmentManager.isDestroyed) return - supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment()) + supportFragmentManager.beginTransaction().replace(binding.fgTrueheme.id, TrueHemeFragment()) .commit() } override fun onBackPressed() { - val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube) - if (fragment is HemoCubeFragment) { + val fragment = supportFragmentManager.findFragmentById(R.id.fg_trueheme) + if (fragment is TrueHemeFragment) { fragment.handleBackButtonPress() } else { super.onBackPressed() } } - fun onErrorReported(msg: String) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() if (!isFinishing) onBackPressed() diff --git a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeFragment.kt index ed85c32..f49d818 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeFragment.kt @@ -16,14 +16,14 @@ import androidx.lifecycle.MutableLiveData import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants -import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.data.constant.TrueHemeCommands import com.example.hpostesting.data.constant.TestStatus -import com.example.hpostesting.data.model.TestState +import com.example.hpostesting.data.model.TestStateTrueHeme import com.example.hpostesting.data.model.patient.DeviceData -import com.example.hpostesting.data.model.patient.toHemoCubeTestData +import com.example.hpostesting.data.model.patient.toTrueHemeTestData import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity -import com.example.hpostesting.presentation.hemocube.HemocubeActivity +import com.example.hpostesting.presentation.trueheme.TrueHemeActivity import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.UIUtils import com.google.firebase.crashlytics.ktx.crashlytics @@ -34,13 +34,12 @@ import kotlin.math.abs import kotlin.math.log10 @Suppress("MemberVisibilityCanBePrivate") -@SuppressLint("SetTextI18n") class TrueHemeFragment : Fragment() { private lateinit var binding: FragmentTruehemeSampleBinding - private val hemoCubeViewModel: TrueHemeViewModel by activityViewModels() + private val trueHemeViewModel: TrueHemeViewModel by activityViewModels() private lateinit var sharedPreferences: SharedPreferences - private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + private val testDetails = DataHolder.selectedTest?.toTrueHemeTestData() private var isOnline = false private var currentDeviceData: DeviceData? = null private var resultData: String = "" @@ -69,17 +68,17 @@ class TrueHemeFragment : Fragment() { private var readingsPerSample = Constants.READINGS_PER_SAMPLE private var uploadedToCloud = false private var uploadedToMolbio = false - lateinit var testState: TestState + lateinit var testState: TestStateTrueHeme override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, ): View { binding = FragmentTruehemeSampleBinding.inflate(inflater, container, false) sharedPreferences = - requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + requireContext().getSharedPreferences("TRUEHEME", Context.MODE_PRIVATE) - testState = TestState( - testDetails = DataHolder.selectedTest?.toHemoCubeTestData(), + testState = TestStateTrueHeme( + testDetails = DataHolder.selectedTest?.toTrueHemeTestData(), ) return binding.root @@ -88,18 +87,21 @@ class TrueHemeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initViews() - listenToHemoCube() + listenToTrueHeme() getDeviceInfo() observeViewModel() } + @SuppressLint("SetTextI18n") private fun initViews() { binding.btnSubmit.setOnClickListener { + binding.btnSubmit.isEnabled = false + binding.btnSubmit.isClickable = false activity?.runOnUiThread { binding.progressBar.visibility = View.VISIBLE binding.btnSubmit.visibility = View.GONE } - hemoCubeViewModel.uploadHemoCubeResultToDatabase( + trueHemeViewModel.uploadTrueHemeResultToDatabase( isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") ) } @@ -109,8 +111,6 @@ class TrueHemeFragment : Fragment() { binding.nameEditText.visibility = View.GONE binding.tvTitle.visibility = View.GONE binding.btnGo.visibility = View.GONE -// binding.btnSubmit.isEnabled = false -// binding.btnSubmit.isClickable = false binding.btnPlacebuffer.visibility = View.GONE binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" @@ -137,7 +137,6 @@ class TrueHemeFragment : Fragment() { checkAndStartProcess() it.visibility = View.GONE } - } if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { @@ -148,40 +147,42 @@ class TrueHemeFragment : Fragment() { } private fun observeViewModel() { - hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> + trueHemeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> if (result == "Success") { uploadedToCloud = true showToast(R.string.test_upload) - hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { - when (it) { - is Result.Success -> { - uploadedToMolbio = true - if (Constants.MOLBIO_INTEGRATION) { + if (Constants.MOLBIO_INTEGRATION) { + trueHemeViewModel.resultUpload.observe(viewLifecycleOwner) { + when (it) { + is Result.Success -> { + uploadedToMolbio = true it.data.data?.get(0)?.rawData?.let { it1 -> - hemoCubeViewModel.updateMolbioFlag( + trueHemeViewModel.updateMolbioFlag( it1._id ) } + handleReadingFinish() } - handleReadingFinish() - } - is Result.Error -> { - binding.btnSubmit.visibility = View.VISIBLE - //Remove this line of code while deploying to IOCL - it.exception.let { message -> - Toast.makeText( - activity, - "An error occurred: $message", - Toast.LENGTH_LONG - ) - .show() + is Result.Error -> { + binding.btnSubmit.visibility = View.VISIBLE + //Remove this line of code while deploying to IOCL + it.exception.let { message -> + Toast.makeText( + activity, + "An error occurred: $message", + Toast.LENGTH_LONG + ) + .show() + } + handleReadingFinish() } - handleReadingFinish() - } - else -> {} + else -> {} + } } + } else { + handleReadingFinish() } } if (result == "Local") { @@ -196,15 +197,15 @@ class TrueHemeFragment : Fragment() { binding.progressBar.visibility = View.GONE } - hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, "")) + trueHemeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, "")) - hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { + trueHemeViewModel.deviceData.observe(viewLifecycleOwner) { currentDeviceData = it } - hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> + trueHemeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> apply { - DataHolder.hemoCubeTestData?.let { + DataHolder.trueHemeTestData?.let { currentDeviceData?.coefficients?.let { coefficients -> // val coefficient1 = coefficients[0] // val coefficient2 = coefficients[1] @@ -215,17 +216,21 @@ class TrueHemeFragment : Fragment() { } } - hemoCubeViewModel.messages.observe(viewLifecycleOwner) { + trueHemeViewModel.messages.observe(viewLifecycleOwner) { binding.tvSubtitle4.text = it } - hemoCubeViewModel.deviceMessages.observe(viewLifecycleOwner) { + trueHemeViewModel.deviceMessages.observe(viewLifecycleOwner) { binding.tvDeviceMessages.text = it } } private fun handleReadingFinish() { if (allReadingsComplete(repeatReadingCount, readingsPerSample) && uploadedToCloud) { + if (validationError) { + trueHemeViewModel.messages.postValue("Error") + return + } activity?.runOnUiThread { binding.btnSubmit.visibility = View.GONE val i = Intent( @@ -234,7 +239,7 @@ class TrueHemeFragment : Fragment() { startActivity(i) } } else { - hemoCubeViewModel.messages.postValue("Reading $repeatReadingCount completed") + trueHemeViewModel.messages.postValue("Reading $repeatReadingCount completed") resetTest() startSampleProcess() } @@ -314,15 +319,15 @@ class TrueHemeFragment : Fragment() { }) } - private fun listenToHemoCube() { - DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData() - hemoCubeViewModel.progressBar.postValue(true) + private fun listenToTrueHeme() { + DataHolder.trueHemeTestData = DataHolder.selectedTest?.toTrueHemeTestData() + trueHemeViewModel.progressBar.postValue(true) val fullReadOutput = StringBuilder() startListening.postValue(true) try { - (activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener { + (activity as TrueHemeActivity).mService.listenToTrueHeme(object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { data?.let { val stringData = String(it) @@ -332,7 +337,7 @@ class TrueHemeFragment : Fragment() { } override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } catch (e: Exception) { @@ -342,20 +347,34 @@ class TrueHemeFragment : Fragment() { } private fun getDeviceInfo() { - hemoCubeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, + trueHemeViewModel.progressBar.postValue(true) + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme( + TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { data?.let { val stringData = String(it) - hemoCubeViewModel.messages.postValue(stringData) + trueHemeViewModel.messages.postValue(stringData) binding.tvSubtitle4.text = stringData } } override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) + } + }) + } + + private fun loadDACValues() { + trueHemeViewModel.progressBar.postValue(true) + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme( + TrueHemeCommands.LOAD_DAC_VALUES, + object : UsbServiceListener { + override fun onUsbRead(data: ByteArray?) { + } + + override fun onUsbError(e: Exception?) { + trueHemeViewModel.progressBar.postValue(false) } }) } @@ -367,11 +386,12 @@ class TrueHemeFragment : Fragment() { resultData += stringData currentResultData += stringData - hemoCubeViewModel.deviceMessages.postValue(currentResultData) + trueHemeViewModel.deviceMessages.postValue(currentResultData) when { resultData.contains("SNE") && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { processV2HardwareId(resultData) + loadDACValues() } (resultData.contains("SN") && !resultData.contains("SNS") && !resultData.contains("SNE") && resultData.length >= 15) && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { @@ -381,18 +401,24 @@ class TrueHemeFragment : Fragment() { (resultData.contains("#LS") && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_STARTED.code) -> { // air reading 1 this.testStatusCode = TestStatus.FIRST_EMPTY_AIR_READING_STARTED.code - hemoCubeViewModel.messages.postValue("Air reading started") + trueHemeViewModel.messages.postValue("Air reading started") } (resultData.contains("#LC") && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code) -> { // air reading 1, send command to print this.testStatusCode = TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code - hemoCubeViewModel.messages.postValue("Air reading completed") + trueHemeViewModel.messages.postValue("Air reading completed") fetchResult() } + (resultData.contains("#RC") && this.testStatusCode < TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code) -> { + this.testStatusCode = TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code + trueHemeViewModel.messages.postValue("EPROM ADC Loaded") + showStartBufferButton() + } + resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> { - hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started)) + trueHemeViewModel.messages.postValue(getString(R.string.buffer_started)) this.testStatusCode = TestStatus.BUFFER_STARTED.code } @@ -414,7 +440,7 @@ class TrueHemeFragment : Fragment() { (resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> { this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code - hemoCubeViewModel.messages.postValue( + trueHemeViewModel.messages.postValue( getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data) ) fetchResult() @@ -422,54 +448,54 @@ class TrueHemeFragment : Fragment() { } resultData.contains("ovf") -> { - hemoCubeViewModel.messages.postValue( + trueHemeViewModel.messages.postValue( getString(R.string.power_bank) ) } currentResultData.contains("#SS2") && this.testStatusCode < TestStatus.FIRST_GAIN_STARTED.code -> { this.testStatusCode = TestStatus.FIRST_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("1.3X Gain Started") + trueHemeViewModel.messages.postValue("1.3X Gain Started") } currentResultData.contains("#SC2") && this.testStatusCode < TestStatus.FIRST_GAIN_COMPLETED.code -> { this.testStatusCode = TestStatus.FIRST_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("1.3X Gain Completed") + trueHemeViewModel.messages.postValue("1.3X Gain Completed") fetchResult() } currentResultData.contains("#SS3") && this.testStatusCode < TestStatus.SECOND_GAIN_STARTED.code -> { this.testStatusCode = TestStatus.SECOND_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("2X Gain Started") + trueHemeViewModel.messages.postValue("2X Gain Started") } currentResultData.contains("#SC3") && this.testStatusCode < TestStatus.SECOND_GAIN_COMPLETED.code -> { this.testStatusCode = TestStatus.SECOND_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("2X Gain Completed") + trueHemeViewModel.messages.postValue("2X Gain Completed") fetchResult() } currentResultData.contains("#SS5") && this.testStatusCode < TestStatus.FORTH_GAIN_STARTED.code -> { this.testStatusCode = TestStatus.FORTH_GAIN_STARTED.code - hemoCubeViewModel.messages.postValue("7.6X Gain Started") + trueHemeViewModel.messages.postValue("7.6X Gain Started") } currentResultData.contains("#SC5") && this.testStatusCode < TestStatus.FORTH_GAIN_COMPLETED.code -> { this.testStatusCode = TestStatus.FORTH_GAIN_COMPLETED.code - hemoCubeViewModel.messages.postValue("7.6X Gain Completed") + trueHemeViewModel.messages.postValue("7.6X Gain Completed") fetchResult() } (resultData.contains("#LS") && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_READING_STARTED.code) -> { // air reading 2 this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_READING_STARTED.code - hemoCubeViewModel.messages.postValue("Air reading started") + trueHemeViewModel.messages.postValue("Air reading started") } (resultData.contains("#LC") && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code) -> { // air reading 2, print values this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code - hemoCubeViewModel.messages.postValue("Air reading completed") + trueHemeViewModel.messages.postValue("Air reading completed") fetchResult() } @@ -481,10 +507,10 @@ class TrueHemeFragment : Fragment() { && this.testStatusCode >= TestStatus.FIRST_EMPTY_AIR_READING_COMPLETED.code && this.testStatusCode < TestStatus.FIRST_EMPTY_AIR_READING_PRINT_COMPLETED.code -> { this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("First air reading completed") + trueHemeViewModel.messages.postValue("First air reading completed") val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { led1Air1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Air1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led3Air1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! @@ -499,10 +525,10 @@ class TrueHemeFragment : Fragment() { && this.testStatusCode >= TestStatus.SECOND_EMPTY_AIR_READING_COMPLETED.code && this.testStatusCode < TestStatus.SECOND_EMPTY_AIR_PRINT_COMPLETED.code -> { this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("Second air reading completed") + trueHemeViewModel.messages.postValue("Second air reading completed") val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { led1Air2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Air2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led3Air2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! @@ -517,10 +543,10 @@ class TrueHemeFragment : Fragment() { && this.testStatusCode >= TestStatus.FIRST_GAIN_COMPLETED.code && this.testStatusCode < TestStatus.FIRST_GAIN_PRINT_COMPLETED.code -> { this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("1.3X gain data gathered") + trueHemeViewModel.messages.postValue("1.3X gain data gathered") val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! @@ -536,10 +562,10 @@ class TrueHemeFragment : Fragment() { && this.testStatusCode >= TestStatus.FIRST_GAIN_PRINT_COMPLETED.code && this.testStatusCode < TestStatus.SECOND_GAIN_PRINT_COMPLETED.code -> { this.testStatusCode = TestStatus.SECOND_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("2X gain data gathered") + trueHemeViewModel.messages.postValue("2X gain data gathered") val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! @@ -555,15 +581,14 @@ class TrueHemeFragment : Fragment() { && this.testStatusCode >= TestStatus.SECOND_GAIN_PRINT_COMPLETED.code && this.testStatusCode < TestStatus.FORTH_GAIN_PRINT_COMPLETED.code -> { this.testStatusCode = TestStatus.FORTH_GAIN_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue("7.6X gain data gathered") + trueHemeViewModel.messages.postValue("7.6X gain data gathered") val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! - led4Gain4 = - resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! + led4Gain4 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! } finishReading() @@ -573,6 +598,7 @@ class TrueHemeFragment : Fragment() { fun finishReading() { repeatReadingCount += 1 + isTestOngoing = false if (readingsPerSample == 1) { activity?.runOnUiThread { @@ -583,7 +609,7 @@ class TrueHemeFragment : Fragment() { binding.ivCheck.visibility = View.VISIBLE } } else { - hemoCubeViewModel.uploadHemoCubeResultToDatabase( + trueHemeViewModel.uploadTrueHemeResultToDatabase( isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") ) } @@ -592,7 +618,7 @@ class TrueHemeFragment : Fragment() { fun handleSampleCompleted() { this.testStatusCode = TestStatus.SAMPLE_PRINT_COMPLETED.code - hemoCubeViewModel.messages.postValue( + trueHemeViewModel.messages.postValue( getString(R.string.data_collected_processing_data) ) @@ -641,23 +667,26 @@ class TrueHemeFragment : Fragment() { if (!hardwareId.isNullOrBlank()) { updateDeviceId(hardwareId) - activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.VISIBLE - } - hemoCubeViewModel.messages.postValue(getString(R.string.start)) } else { - hemoCubeViewModel.messages.postValue("Config error") + trueHemeViewModel.messages.postValue("Config error") } if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) { assignDefaultDevice(resultData) - testState.allErrorMessages += "Calibration configuration for this device id is not found\n" +// testState.allErrorMessages += "Calibration configuration for this device id is not found\n" } if (!Constants.BUFFER_INTENSITY_THRESHOLDS.containsKey(deviceHardwareId)) { - testState.allErrorMessages += "ADC thresholds for this device id are not found\n" +// testState.allErrorMessages += "ADC thresholds for this device id are not found\n" } } + fun showStartBufferButton() { + activity?.runOnUiThread { + binding.btnPlacebuffer.visibility = View.VISIBLE + } + trueHemeViewModel.messages.postValue(getString(R.string.start)) + } + fun extractV1HardwareId(input: String): String? { val regex = Regex("SN (\\S+)") val matchResult = regex.find(input) @@ -670,12 +699,12 @@ class TrueHemeFragment : Fragment() { if (!hardwareId.isNullOrBlank()) { updateDeviceId(hardwareId) - activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.VISIBLE - } - hemoCubeViewModel.messages.postValue(getString(R.string.start)) +// activity?.runOnUiThread { +// binding.btnPlacebuffer.visibility = View.VISIBLE +// } +// hemoCubeViewModel.messages.postValue(getString(R.string.start)) } else { - hemoCubeViewModel.messages.postValue("Config error") + trueHemeViewModel.messages.postValue("Config error") } if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) { @@ -690,10 +719,10 @@ class TrueHemeFragment : Fragment() { fun assignDefaultDevice(configData: String) { deviceHardwareId = "HCV-000-3001" testStatusCode = TestStatus.CONFIG_COMPLETED.code - activity?.runOnUiThread { - binding.btnPlacebuffer.visibility = View.VISIBLE - } - hemoCubeViewModel.messages.postValue(getString(R.string.start)) +// activity?.runOnUiThread { +// binding.btnPlacebuffer.visibility = View.VISIBLE +// } +// hemoCubeViewModel.messages.postValue(getString(R.string.start)) } fun extractV2HardwareId(input: String): String? { @@ -724,7 +753,7 @@ class TrueHemeFragment : Fragment() { private fun processResult() { try { - hemoCubeViewModel.messages.postValue(getString(R.string.processing_result)) + trueHemeViewModel.messages.postValue(getString(R.string.processing_result)) val deviceLog = resultData val pInfo = requireActivity().packageManager.getPackageInfo( @@ -736,7 +765,8 @@ class TrueHemeFragment : Fragment() { val led2Average = log10(led2BufferForDevice.div(led2SampleForDevice)) val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice)) val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice)) - val deviceRatio = led4Average / led1Average + val deviceRatio = led2Average / led1Average + val borderlineMetric = (led1Average - led2Average) / deviceRatio if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) ?.get(0)!! @@ -750,10 +780,10 @@ class TrueHemeFragment : Fragment() { 3 )?.get(0)!! ) { - validationError = true - testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)" +// validationError = true +// testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)" activity?.runOnUiThread { - binding.errorMessage.text = getString(R.string.error_improper_buffer_low) +// binding.errorMessage.text = getString(R.string.error_improper_buffer_low) // binding.errorMessage.visibility = View.VISIBLE } } @@ -770,12 +800,12 @@ class TrueHemeFragment : Fragment() { 3 )?.get(1)!! ) { - validationError = true - testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n" +// validationError = true +// testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n" activity?.runOnUiThread { - binding.errorMessage.text = - getString(R.string.error_improper_buffer_high) - binding.errorMessage.visibility = View.VISIBLE +// binding.errorMessage.text = + getString(R.string.error_improper_buffer_high) +// binding.errorMessage.visibility = View.VISIBLE } } @@ -813,46 +843,46 @@ class TrueHemeFragment : Fragment() { calculatedPredictedDenovixRatio = fittedAbs3.div(fittedAbs1) - val slope = (led1Average - led2Average) / (435 - 415) - val calculatedSlopeRatio = abs(led3Average / slope) + val slope = (led4Average - led1Average) / (431 - 411) + val calculatedSlopeRatio = abs(led2Average / slope) val slopeClass = slopeRatioClassification(calculatedSlopeRatio) if (fittedAbs1 <= fittedAbs2) { - validationError = true - testState.allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n" +// validationError = true +// testState.allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n" activity?.runOnUiThread { - binding.errorMessage.text = getString(R.string.error_invalid_test) +// binding.errorMessage.text = getString(R.string.error_invalid_test) // binding.errorMessage.visibility = View.VISIBLE } } if (fittedAbs1 < 0 || fittedAbs2 < 0 || fittedAbs3 < 0 || fittedAbs4 < 0) { - validationError = true +// validationError = true activity?.runOnUiThread { binding.errorMessage.text = getString(R.string.error_negative_abs) // binding.errorMessage.visibility = View.VISIBLE } } - if ((led1Average < 0.7 || led2Average < 0.7 || led3Average < 0.7 || led4Average < 0.7) && calculatedSlopeRatio > 35.0) { + val absorbanceLowerLimit = 0.0 + if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = - "Severely Low Hb. Repeat test with 12 ul in 2 ml Buffer" + binding.errorMessage.text = "Invalid" binding.errorMessage.visibility = View.VISIBLE } } if (fittedAbs3 < 0.1) { - validationError = true - testState.allErrorMessages += "Error: Low Hb. Repeat test" + "\n" +// validationError = true +// testState.allErrorMessages += "Error: Low Hb. Repeat test" + "\n" activity?.runOnUiThread { - binding.errorMessage.text = "Error: Low Hb. Repeat test" +// binding.errorMessage.text = "Error: Low Hb. Repeat test" // binding.errorMessage.visibility = View.VISIBLE } } - DataHolder.hemoCubeTestData?.apply { + DataHolder.trueHemeTestData?.apply { deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString() led1Buffer = led1BufferForDevice led2Buffer = led2BufferForDevice @@ -881,21 +911,32 @@ class TrueHemeFragment : Fragment() { .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) this.deviceRatioClass = deviceRatioClassification(deviceRatio) + this.borderlineMethod2Class = reclassifyWithBorderlineMethod2(deviceRatio, deviceRatioBorderlineThresholds(deviceRatio), led2Average) this.slopeRatioClass = slopeClass - this.classificationResult = deviceRatioClass //findResult(calculatedRatio) - hemoCubeViewModel.messages.postValue("${this.deviceRatioClass} ${if (led4Average < 0.17) " - Low Hb" else ""}\n") - if (DataHolder.hemoCubeTestData?.testType == "HB") - hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4") + this.classificationResult = findResultWithAdditionalMethods( + deviceRatio, + deviceRatioClass, + borderlineMetric + ) + trueHemeViewModel.messages.postValue( + "${this.classificationResult} \n Device Ratio: ${ + "%.3f".format( + this.deviceRatio + ) + }" + ) + if (DataHolder.trueHemeTestData?.testType == "HB") + trueHemeViewModel.messages.postValue("Hb: $calculatedHb4") this.errorMessages = testState.allErrorMessages this.resultData = deviceLog - this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString() + this.batteryLevel = trueHemeViewModel.getBatteryLevel().toString() this.batteryCapacity = - hemoCubeViewModel.getBatteryCapacity(requireContext()).toString() + trueHemeViewModel.getBatteryCapacity(requireContext()).toString() this.batteryMaxCapacity = - hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString() - this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString() + trueHemeViewModel.getBatteryMaxCapacity(requireContext()).toString() + this.batteryTemperature = trueHemeViewModel.getBatteryTemperature().toString() this.batteryVoltage = - hemoCubeViewModel.getBatteryVoltage(requireContext()).toString() + trueHemeViewModel.getBatteryVoltage(requireContext()).toString() } if (!isUsingExistingBuffer) { @@ -917,50 +958,97 @@ class TrueHemeFragment : Fragment() { } } - fun findResult(calculatedRatio: Double?): String { + fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String { try { - hemoCubeViewModel.messages.postValue("result classification") - if (calculatedRatio != null) { - if (calculatedRatio < 0.05) - return getString(R.string.error_repeat_test_higher_volume) - if (calculatedRatio in 0.05..0.155) { - return getString(R.string.normal) + if (deviceRatio != null && led2Average != null) { + if (deviceRatioClass == "Negative Borderline") { + return if (led2Average >= 0.15) + "Borderline. Normal" + else + "Borderline. Sickle Cell Trait" + } + if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { + return if (led2Average >= 0.19) + "Borderline. Sickle Cell Trait" + else + "Borderline. Sickle Cell Disease" } - if (calculatedRatio in 0.155..0.175) - return getString(R.string.negative_borderline) - if (calculatedRatio in 0.175..0.22) - return getString(R.string.sickle_cell_trait) - if (calculatedRatio in 0.22..0.25) - return getString(R.string.positive_for_sickle_cell) - if (calculatedRatio in 0.25..0.35) - return getString(R.string.sickle_cell_disease) - if (calculatedRatio > 0.35) - return getString(R.string.error_repeat_test_lower_volume) - } else { - return getString(R.string.invalid) } } catch (e: Exception) { - showToast(R.string.error_classification) - Firebase.crashlytics.recordException(e) - return getString(R.string.error) + handleException(e) + return "Error" } - return getString(R.string.invalid) + return deviceRatioClass.toString() + } + + fun findResultWithAdditionalMethods( + deviceRatio: Double?, + deviceRatioClass: String?, + borderlineMetric: Double?, + ): String { + try { +// hemoCubeViewModel.messages.postValue("post classification checks") + if (deviceRatio != null && borderlineMetric != null) { + if (deviceRatioClass == "Negative Borderline") { + return if (borderlineMetric >= 2.4) + "Borderline. Normal" + else + "Borderline. Sickle Cell Trait" + } + if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { + return if (borderlineMetric >= 1.34) + "Borderline. Sickle Cell Trait" + else + "Borderline. Sickle Cell Disease" + } + } + } catch (e: Exception) { + handleException(e) + return "Error" + } + return deviceRatioClass.toString() + } + + fun deviceRatioBorderlineThresholds(ratio: Double?): String { + try { + if (ratio != null) { + val roundedRatio = String.format("%.3f", ratio).toDouble() + if (roundedRatio >= 0.11 && roundedRatio < 0.237) { +// setSubtitleTextColor(R.color.green_2) + return "Normal" + } + if (roundedRatio in 0.237..0.242) + return "Negative Borderline" + if (roundedRatio in 0.242..0.318) + return "Sickle Cell Trait" + if (roundedRatio >= 0.318 && roundedRatio < 0.356) + return "Positive for Sickle Cell. HPLC for Confirmation" + if (roundedRatio in 0.356..0.7) + return "Sickle Cell Disease" + } else { + return "Invalid" + } + } catch (e: Exception) { + handleException(e) + return "Error" + } + return "Invalid" } fun deviceRatioClassification(ratio: Double?): String { try { if (ratio != null) { - if (ratio in 0.2..0.29) { + if (ratio in 0.16..0.23) { // setSubtitleTextColor(R.color.green_2) return "Normal" } - if (ratio in 0.29..0.32) - return "Negative Borderline, Repeat Test" - if (ratio in 0.32..0.35) + if (ratio in 0.23..0.25) + return "Negative Borderline" + if (ratio in 0.25..0.31) return "Sickle Cell Trait" - if (ratio in 0.35..0.38) + if (ratio in 0.31..0.36) return "Positive for Sickle Cell. HPLC for Confirmation" - if (ratio in 0.38..0.5) + if (ratio in 0.36..0.7) return "Sickle Cell Disease" } else { return "Invalid" @@ -985,7 +1073,7 @@ class TrueHemeFragment : Fragment() { fun slopeRatioClassification(ratio: Double?): String { try { - hemoCubeViewModel.messages.postValue("result classification") + trueHemeViewModel.messages.postValue("result classification") if (ratio != null) { if (ratio in 0.0..30.0) return getString(R.string.normal) @@ -1010,7 +1098,7 @@ class TrueHemeFragment : Fragment() { private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { try { - hemoCubeViewModel.messages.postValue("result classification") + trueHemeViewModel.messages.postValue("result classification") if (predictedDenovixRatio != null) { if (predictedDenovixRatio in 0.0..0.16) { // activity?.runOnUiThread { @@ -1047,103 +1135,96 @@ class TrueHemeFragment : Fragment() { } private fun startBufferProcess() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) activity?.runOnUiThread { binding.btnPlacebuffer.visibility = View.GONE } - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.START_BUFFER_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_BUFFER_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun startSampleProcess() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.START_SAMPLE, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_SAMPLE, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun sendFirstGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.FIRST_GAIN_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.FIRST_GAIN_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun sendSecondGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.SECOND_GAIN_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.SECOND_GAIN_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun sendThirdGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.THIRD_GAIN_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.THIRD_GAIN_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun sendForthGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.FORTH_GAIN_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.FORTH_GAIN_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } private fun fetchResult() { - hemoCubeViewModel.progressBar.postValue(true) + trueHemeViewModel.progressBar.postValue(true) - (activity as HemocubeActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.PRINT_COMMAND, + (activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.PRINT_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) {} override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) + trueHemeViewModel.progressBar.postValue(false) } }) } @@ -1153,8 +1234,4 @@ class TrueHemeFragment : Fragment() { val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0 return coefficient1 * ratio + coefficient2 } - - private fun reconnect() { - (activity as HemocubeActivity).reconnectDevice() - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeViewModel.kt index cbbc818..e50bd1c 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/trueheme/TrueHemeViewModel.kt @@ -18,7 +18,7 @@ import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.dao.HemoCubeBufferDao -import com.example.hpostesting.data.dao.HemoCubeDao +import com.example.hpostesting.data.dao.TrueHemeDao import com.example.hpostesting.data.datasource.LocalFileDataSource import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.log.UploadLogsResponse @@ -29,8 +29,8 @@ import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData -import com.example.hpostesting.data.model.patient.HemoCubeTestData -import com.example.hpostesting.data.model.patient.toHemoCubeTestData +import com.example.hpostesting.data.model.patient.TrueHemeTestData +import com.example.hpostesting.data.model.patient.toTrueHemeTestData import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateResponse import com.example.hpostesting.data.model.updates.DeviceUpdateRequest @@ -52,7 +52,7 @@ import javax.inject.Inject @Suppress("MemberVisibilityCanBePrivate") @HiltViewModel class TrueHemeViewModel @Inject constructor( - private val hemoCubeDao: HemoCubeDao, + private val trueHemeDao: TrueHemeDao, private val hemoCubeBufferDao: HemoCubeBufferDao, private val repository: Repository, private val logFileManager: LogFileManager, @@ -61,10 +61,10 @@ class TrueHemeViewModel @Inject constructor( ) : ViewModel() { var isServiceConnected = false val progressBar = MutableLiveData(false) - private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + private val testDetails = DataHolder.selectedTest?.toTrueHemeTestData() val messages = MutableLiveData() private val sharedPreference = - context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + context.getSharedPreferences("TRUEHEME", Context.MODE_PRIVATE) private val workManager = WorkManager.getInstance(context) @@ -79,16 +79,20 @@ class TrueHemeViewModel @Inject constructor( val checkUpdate = MutableLiveData>() val deviceUpdate = MutableLiveData>() + val downloadcertificate = MutableLiveData>() val uploadLogs = MutableLiveData?>() + // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) private val _networkStatusLiveData = NetworkStatusLiveData(context) - val allUserData = hemoCubeDao.getAll() + val allUserData = trueHemeDao.getAll() + val allPendingUserToUpload = MutableLiveData>() val allKitTestData = hemoCubeBufferDao.getAll() val deviceData = MutableLiveData() + val networkStatusLiveData: LiveData get() = _networkStatusLiveData val deviceMessages = MutableLiveData() @@ -100,7 +104,7 @@ class TrueHemeViewModel @Inject constructor( context.registerReceiver(null, ifilter) } - fun uploadHemoCubeResultToDatabase( + fun uploadTrueHemeResultToDatabase( isOnline: Boolean, testStatus: Boolean, kitSerial: String?, ) = viewModelScope.launch { if (kitSerial != null) { @@ -117,7 +121,7 @@ class TrueHemeViewModel @Inject constructor( testDetails?.testTime = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Calendar.getInstance().time) - hemoCubeDao.insertAll(testDetails!!) + trueHemeDao.insertAll(testDetails!!) fireBaseUpload.postValue("Local") } } catch (e: Exception) { @@ -153,6 +157,13 @@ class TrueHemeViewModel @Inject constructor( } } + fun downloadClientCertificate() = viewModelScope.launch { + downloadcertificate.postValue(Result.Loading()) + repository.downloadClientCertificate().let { + downloadcertificate.postValue(it) + } + } + fun startPeriodicCheckUpdate() { val periodicRequest = PeriodicWorkRequestBuilder( repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES @@ -176,8 +187,11 @@ class TrueHemeViewModel @Inject constructor( } } } + fun uploadPendingUser() = viewModelScope.launch { + allPendingUserToUpload.postValue(trueHemeDao.getPendingUser(false)) + } - fun uploadHemoCubeResultToDatabaseForBufferCheck( + fun uploadTrueHemeResultToDatabaseForBufferCheck( isOnline: Boolean, bufferCheckData: BufferCheckData, ) = @@ -230,7 +244,7 @@ class TrueHemeViewModel @Inject constructor( } } - fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) = + fun uploadTrueHemeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) = viewModelScope.launch { addResultTestToDbforbuffercheck(bufferCheckData) } @@ -240,56 +254,57 @@ class TrueHemeViewModel @Inject constructor( } fun parseData() { - testDetails?.deviceRatio = DataHolder.hemocubeResult - testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() + testDetails?.deviceRatio = DataHolder.trueHemeResult + testDetails?.resultData = DataHolder.trueHemeTestData?.resultData.toString() testDetails?.location = DataHolder.location testDetails?.testTime = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Calendar.getInstance().time) - testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion - testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId + testDetails?.appVersion = DataHolder.trueHemeTestData?.appVersion + testDetails?.deviceId = DataHolder.trueHemeTestData?.deviceId testDetails?.deviceSerialNumber = sharedPreference.getString(Constants.USER_ID, "").toString() testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString() - testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer - testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer - testDetails?.led3Buffer = DataHolder.hemoCubeTestData?.led3Buffer - testDetails?.led4Buffer = DataHolder.hemoCubeTestData?.led4Buffer - testDetails?.led1Sample = DataHolder.hemoCubeTestData?.led1Sample - testDetails?.led2Sample = DataHolder.hemoCubeTestData?.led2Sample - testDetails?.led3Sample = DataHolder.hemoCubeTestData?.led3Sample - testDetails?.led4Sample = DataHolder.hemoCubeTestData?.led4Sample - testDetails?.led1Average = DataHolder.hemoCubeTestData?.led1Average - testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average - testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average - testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average - testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 - testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 - testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 - testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 - testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio - testDetails?.slopeRatio = DataHolder.hemoCubeTestData?.slopeRatio - testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio - testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio - testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients - testDetails?.incubationTime = DataHolder.hemoCubeTestData?.incubationTime.toString() - testDetails?.name = DataHolder.hemoCubeTestData?.name.toString() - testDetails?.birthYear = DataHolder.hemoCubeTestData?.birthYear.toString() - testDetails?.userImageURL = DataHolder.hemoCubeTestData?.userImageURL.toString() - testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! - testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() - testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString() - testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString() - testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString() - testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() - testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() - testDetails?.batteryMaxCapacity = DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString() - testDetails?.batteryTemperature = DataHolder.hemoCubeTestData?.batteryTemperature.toString() - testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString() - testDetails?.quickCapture = DataHolder.hemoCubeTestData?.quickCapture!! - testDetails?.solution = DataHolder.hemoCubeTestData?.solution - testDetails?.concentration = DataHolder.hemoCubeTestData?.concentration - testDetails?.volume = DataHolder.hemoCubeTestData?.volume + testDetails?.led1Buffer = DataHolder.trueHemeTestData?.led1Buffer + testDetails?.led2Buffer = DataHolder.trueHemeTestData?.led2Buffer + testDetails?.led3Buffer = DataHolder.trueHemeTestData?.led3Buffer + testDetails?.led4Buffer = DataHolder.trueHemeTestData?.led4Buffer + testDetails?.led1Sample = DataHolder.trueHemeTestData?.led1Sample + testDetails?.led2Sample = DataHolder.trueHemeTestData?.led2Sample + testDetails?.led3Sample = DataHolder.trueHemeTestData?.led3Sample + testDetails?.led4Sample = DataHolder.trueHemeTestData?.led4Sample + testDetails?.led1Average = DataHolder.trueHemeTestData?.led1Average + testDetails?.led2Average = DataHolder.trueHemeTestData?.led2Average + testDetails?.led3Average = DataHolder.trueHemeTestData?.led3Average + testDetails?.led4Average = DataHolder.trueHemeTestData?.led4Average + testDetails?.abs1 = DataHolder.trueHemeTestData?.abs1 + testDetails?.abs2 = DataHolder.trueHemeTestData?.abs2 + testDetails?.abs3 = DataHolder.trueHemeTestData?.abs3 + testDetails?.abs4 = DataHolder.trueHemeTestData?.abs4 + testDetails?.deviceRatio = DataHolder.trueHemeTestData?.deviceRatio + testDetails?.slopeRatio = DataHolder.trueHemeTestData?.slopeRatio + testDetails?.predictedDenovixRatio = DataHolder.trueHemeTestData?.predictedDenovixRatio + testDetails?.calculatedRatio = DataHolder.trueHemeTestData?.calculatedRatio + testDetails?.coefficients = DataHolder.trueHemeTestData?.coefficients + testDetails?.incubationTime = DataHolder.trueHemeTestData?.incubationTime.toString() + testDetails?.name = DataHolder.trueHemeTestData?.name.toString() + testDetails?.birthYear = DataHolder.trueHemeTestData?.birthYear.toString() + testDetails?.userImageURL = DataHolder.trueHemeTestData?.userImageURL.toString() + testDetails?.classificationResult = DataHolder.trueHemeTestData?.classificationResult!! + testDetails?.prdClassification = DataHolder.trueHemeTestData?.prdClassification.toString() + testDetails?.deviceRatioClass = DataHolder.trueHemeTestData?.deviceRatioClass.toString() + testDetails?.slopeRatioClass = DataHolder.trueHemeTestData?.slopeRatioClass.toString() + testDetails?.borderlineMethod2Class = DataHolder.trueHemeTestData?.borderlineMethod2Class.toString() + testDetails?.errorMessages = DataHolder.trueHemeTestData?.errorMessages.toString() + testDetails?.batteryLevel = DataHolder.trueHemeTestData?.batteryLevel.toString() + testDetails?.batteryCapacity = DataHolder.trueHemeTestData?.batteryCapacity.toString() + testDetails?.batteryMaxCapacity = DataHolder.trueHemeTestData?.batteryMaxCapacity.toString() + testDetails?.batteryTemperature = DataHolder.trueHemeTestData?.batteryTemperature.toString() + testDetails?.batteryVoltage = DataHolder.trueHemeTestData?.batteryVoltage.toString() + testDetails?.quickCapture = DataHolder.trueHemeTestData?.quickCapture!! + testDetails?.solution = DataHolder.trueHemeTestData?.solution + testDetails?.concentration = DataHolder.trueHemeTestData?.concentration + testDetails?.volume = DataHolder.trueHemeTestData?.volume } private fun addResultTestToDb() { @@ -299,7 +314,7 @@ class TrueHemeViewModel @Inject constructor( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Calendar.getInstance().time) - when (val response = repository.addTestToDatabase(testDetails)) { + when (val response = repository.addTestToDatabaseTrue(testDetails)) { is Response.Success -> { val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0) with(sharedPreference.edit()) { @@ -309,31 +324,33 @@ class TrueHemeViewModel @Inject constructor( Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Success") testDetails.localFlag = true - uploadResult( - MolbioV2ResultRequest( - mutableListOf( - MolbioV2Result( - rawData = testDetails, - analysisId = testDetails._id, - analysisDate = testDetails.testTime, - analysisStatus = testDetails.classificationResult, - thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(), - interpretation = testDetails.classificationResult, - testId = testDetails._id, - testTime = testDetails.testTime, - collectionTime = testDetails.testTime, - expiryTime = testDetails.testTime, + if (Constants.MOLBIO_INTEGRATION) { + uploadResult( + MolbioV2ResultRequest( + mutableListOf( + MolbioV2Result( + rawData = testDetails, + analysisId = testDetails._id, + analysisDate = testDetails.testTime, + analysisStatus = testDetails.classificationResult, + thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(), + interpretation = testDetails.classificationResult, + testId = testDetails._id, + testTime = testDetails.testTime, + collectionTime = testDetails.testTime, + expiryTime = testDetails.testTime, + ) ) ) ) - ) - hemoCubeDao.insertAll(testDetails) + } + trueHemeDao.insertAll(testDetails) } is Response.Error -> { Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") - hemoCubeDao.insertAll(testDetails) + trueHemeDao.insertAll(testDetails) } else -> {} @@ -345,12 +362,12 @@ class TrueHemeViewModel @Inject constructor( } } - fun bulkAddResultTestToDb(userData: HemoCubeTestData) { + fun bulkAddResultTestToDb(userData: TrueHemeTestData) { viewModelScope.launch { userData.reportUploadTime = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Calendar.getInstance().time) - when (repository.addTestToDatabase(userData)) { + when (repository.addTestToDatabaseTrue(userData)) { is Response.Success -> { fireBaseBulkUpload.postValue("Success") updateLocalFlag(userData._id) @@ -364,21 +381,22 @@ class TrueHemeViewModel @Inject constructor( } private fun updateLocalFlag(userId: String) = viewModelScope.launch { - hemoCubeDao.updateFieldById(id = userId, true) + trueHemeDao.updateFieldById(id = userId, true) } fun updateMolbioFlag(userId: String) = viewModelScope.launch { - hemoCubeDao.updateMolbioFlag(id = userId, true) + trueHemeDao.updateMolbioFlag(id = userId, true) } - fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { - hemoCubeDao.insertAll(userData) + fun addUser(userData: TrueHemeTestData) = viewModelScope.launch { + trueHemeDao.insertAll(userData) } fun deleteById(userId: String) = viewModelScope.launch { - hemoCubeDao.deleteById(id = userId) + trueHemeDao.deleteById(id = userId) } + private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { viewModelScope.launch { try { @@ -394,6 +412,8 @@ class TrueHemeViewModel @Inject constructor( Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") } + + else -> {} } } catch (e: Exception) { Log.e("Testdb", "Exception during data upload: ${e.message}") @@ -408,7 +428,7 @@ class TrueHemeViewModel @Inject constructor( } fun getLocalUserDataForCsv(context: Context): Boolean { - val localUserDataLiveData: LiveData> = hemoCubeDao.getAll() + val localUserDataLiveData: LiveData> = trueHemeDao.getAll() // Observe the LiveData to get the actual data when available localUserDataLiveData.observeForever { localUserData -> @@ -508,13 +528,13 @@ class TrueHemeViewModel @Inject constructor( return maxCapacity } - fun createCSV(hemoCubeTestData: List, appContext: Context) = + fun createCSV(trueHemeTestData: List, appContext: Context) = viewModelScope.launch { val fileName = "HPOS${getCurrentDate()}.csv" - if (localFileDataSource.exportDataToCSV(fileName, hemoCubeTestData)) { - hemoCubeTestData.forEach { data -> + if (localFileDataSource.exportDataToCSV(fileName, trueHemeTestData)) { + trueHemeTestData.forEach { data -> data.localFlag = true - hemoCubeDao.updateCSVFieldById( + trueHemeDao.updateCSVFieldById( data._id, true )