Compare commits

..

37 Commits

Author SHA1 Message Date
Mariya
4b059bc953 fixed some issues 2024-03-11 17:33:34 +05:30
Mariya
320ceae26a fixed issues while merging 2024-03-11 17:23:28 +05:30
sanjay
08a781a706 Merge remote-tracking branch 'origin/dev-molbio-result-upload-jithu' into dev-molbio-result-upload-jithu
# Conflicts:
#	app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
2024-03-11 17:13:15 +05:30
sanjay
8c4fedfe28 code to decrypt and login using locally saved credentials 2024-03-11 17:08:02 +05:30
Mariya
71818e1115 Merge branch 'dev' into dev-molbio-result-upload-jithu
# Conflicts:
#	app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt
2024-03-11 15:14:44 +05:30
Mariya
d7c1508397 changed the condition for fetching device provision details from firebase 2024-03-11 13:01:58 +05:30
chandrashekhar reddy
d701ee4f6d removed the finish for btnNewKit in HomeFragment 2024-03-09 16:20:29 +05:30
chandrashekhar reddy
e4b237bb9a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 16:13:54 +05:30
chandrashekhar reddy
372489330a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 15:20:49 +05:30
chandrashekhar reddy
0c10e5a920 Merge remote-tracking branch 'origin/dev' into dev 2024-03-09 12:27:22 +05:30
chandrashekhar reddy
045bda26ff Rearranging the project structure, so it will east to understand and following proper clean code rules 2024-03-09 12:26:59 +05:30
Mariya
b31e5e6c06 removed getting null values from result upload 2024-03-07 13:30:38 +05:30
sanjay
3913aedefc encryption code integrated 2024-03-07 12:13:12 +05:30
Mariya
53c36d3cf9 added different id and set as primary key for testing twice with same sample Id and uploading the result, offline ,issue fixed, and set ADMIN as user that can only download and export CSV file, for collecting user Data 2024-03-07 12:11:27 +05:30
sanjay
b554f64b51 setting up encryption 2024-03-07 09:55:56 +05:30
jithu
95bb428041 data upload duplication fixed-molbio & firebase 2024-03-05 17:20:18 +05:30
chandrashekhar reddy
f922f585b5 Merge remote-tracking branch 'origin/dev' into dev 2024-03-05 14:46:12 +05:30
chandrashekhar reddy
1742363f1a added deviceUpdateGlobal field in HomeFragment 2024-03-05 14:45:47 +05:30
Mariya
ba9564d867 added new kit button and logout button for offline test 2024-03-05 14:44:06 +05:30
Mariya
1aaf2ba485 sanitize the results values if the result is NaN or infinity 2024-03-04 18:02:07 +05:30
Mariya
85756a7052 commented code for unregistereceiver 2024-03-04 16:47:55 +05:30
Mariya Varghese
0141c2791e Merge branch 'dev-check-apk-update' into 'dev'
app update and other api calls managing for molbio

See merge request sminnovations/hpos!39
2024-03-04 11:12:21 +00:00
Mariya Varghese
a52538e72d Merge branch 'dev' into 'dev-check-apk-update'
# Conflicts:
#   app/build.gradle
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt
#   build.gradle
#   gradle/wrapper/gradle-wrapper.properties
2024-03-04 11:11:13 +00:00
Mariya
c9d0c440e3 added code for sanitize result upload values if if the result is NAN or infinity for molbio integration 2024-03-04 14:48:43 +05:30
Mariya
20f408230e api calls managing, and error resolving for molbio 2024-03-02 19:37:24 +05:30
Mariya
c8d5d41c81 api calls maintaining for molbio 2024-03-02 15:41:17 +05:30
Mariya
210c9fed5d added code for usb permission 2024-03-01 16:21:27 +05:30
Mariya
b68ec45642 reduced number of api calls in home screen 2024-03-01 13:37:16 +05:30
Mariya
1e5afa0a5c reduced number api calls for bigtec 2024-03-01 12:38:19 +05:30
Mariya
80ab69c772 added code for uploading logs only once 2024-02-29 14:18:09 +05:30
Mariya
f7dc879c75 added code related offline bulkupload 2024-02-28 15:17:36 +05:30
Mariya
e8b5d12db5 removed unwanted toast messages 2024-02-28 15:12:21 +05:30
Mariya
626dd380ab Apk update successfully added 2024-02-28 14:46:06 +05:30
Mariya
70b0b93f57 Apk Update Code Added 2024-02-27 20:44:32 +05:30
Mariya
5cdc156f33 Apk Update Code Added 2024-02-27 16:49:25 +05:30
Mariya
71d298cd69 Apk Update Code Added 2024-02-27 14:59:03 +05:30
Mariya
bb6f4ee859 Apk Update Code Added 2024-02-27 12:43:14 +05:30
92 changed files with 3358 additions and 1876 deletions

View File

@@ -19,8 +19,8 @@ android {
applicationId "in.sminnovations.hpostesting.dev"
minSdk 21
targetSdk 34
versionCode 114
versionName "2.1.114"
versionCode 120
versionName "2.1.120"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -25,6 +25,7 @@
<application
android:name="com.example.hpostesting.HPOSTestingApplication"
android:largeHeap="true"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@@ -1,14 +0,0 @@
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 {
fun getProperty(key: String): String
}
interface DeviceCommunicationHandler {
fun sendAndListenToDevice(command: TrueHemeCommands, listener: UsbServiceListener)
}

View File

@@ -3,13 +3,12 @@ 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"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTEGRATION = false
const val MOLBIO_INTEGRATION = true
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI"
@@ -240,20 +239,6 @@ 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<String, List<List<Double>>> = mapOf<String, List<List<Double>>>(
"HCV-000-3001" to listOf(
listOf(1.0, 0.0), // LED1, 435nm

View File

@@ -1,8 +1,7 @@
package com.example.hpostesting.data
package com.example.hpostesting.data.constant
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
@@ -24,10 +23,8 @@ object DataHolder {
val intensityReferenceArray = ArrayList<Double>()
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
}

View File

@@ -1,9 +1,18 @@
package com.example.hpostesting.data.constant
enum class HemoCubeCommands(val command: String) {
startBuffer("B\r"),
runDiagnostics("D\r"),
startSample("S\r"),
getSample("P\r"),
getDeviceId("I\r"),
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"),
}

View File

@@ -1,18 +0,0 @@
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"),
}

View File

@@ -5,6 +5,7 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
@Dao
@@ -12,6 +13,12 @@ interface HemoCubeDao {
@Query("SELECT * from hemo_cube_test_table")
fun getAll(): LiveData<List<HemoCubeTestData>>
@Query("SELECT * from hemo_cube_test_table WHERE molbioFlag=false")
fun getMolbioPending(): List<HemoCubeTestData>
@Query("SELECT * from hemo_cube_test_table WHERE localFlag=false")
fun getFirebasePending():List<HemoCubeTestData>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(hemoCubeTestData: HemoCubeTestData)
@@ -30,7 +37,7 @@ interface HemoCubeDao {
@Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id")
suspend fun updateCSVFieldById(id: String, newValue: Boolean)
@Query("SELECT * from hemo_cube_test_table WHERE molbioFlag = :status")
suspend fun getPendingUser(status: Boolean): List<HemoCubeTestData>
@Query("SELECT * from hemo_cube_test_table WHERE localFlag = 0")
fun getPendingUser(): LiveData<List<HemoCubeTestData>>
}

View File

@@ -6,11 +6,10 @@ 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,TrueHemeTestData::class],
entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class],
version = 29,
exportSchema = false
)
@@ -18,6 +17,5 @@ import com.example.hpostesting.data.model.patient.UserData
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun hemoCubeDao(): HemoCubeDao
abstract fun trueHemeDao(): TrueHemeDao
abstract fun hemoCubeBufferDao(): HemoCubeBufferDao
}

View File

@@ -1,36 +0,0 @@
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<List<TrueHemeTestData>>
@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<TrueHemeTestData>
}

View File

@@ -1,7 +1,6 @@
package com.example.hpostesting.data.datasource
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.TrueHemeTestData
interface LocalFileDataSource {
@@ -9,11 +8,7 @@ interface LocalFileDataSource {
fun saveTextToDisk(filepath: String, contents: String)
// fun exportDataToCSV(
// fileName: String, dataList: List<HemoCubeTestData>,
// ): Boolean
fun exportDataToCSV(
fileName: String, dataList: List<TrueHemeTestData>,
fileName: String, dataList: List<HemoCubeTestData>,
): Boolean
}

View File

@@ -2,7 +2,6 @@ package com.example.hpostesting.data.datasource
import android.os.Environment
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.TrueHemeTestData
import com.opencsv.CSVWriter
import java.io.File
import java.io.FileWriter
@@ -26,7 +25,7 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
}
override fun exportDataToCSV(
fileName: String, dataList: List<TrueHemeTestData>,
fileName: String, dataList: List<HemoCubeTestData>,
): Boolean {
try {
val formattedFileName = fileName.replace(
@@ -90,8 +89,9 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
)
csvWriter.writeNext(header)
// Write data rows
for (data in dataList) {
// Filter and write data rows where testStatus is true
val filteredDataList = dataList.filter { it.testStatus == true }
for (data in filteredDataList) {
val row = arrayOf(
data._id,
data.name,

View File

@@ -1,44 +0,0 @@
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
)

View File

@@ -1,7 +1,6 @@
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,
@@ -23,7 +22,7 @@ data class MolbioV2Result(
val `operator`: String? = "",
val patientId: Int? = 4545,
val pregnancy: Boolean? = false,
val rawData: TrueHemeTestData? = TrueHemeTestData(),
val rawData: HemoCubeTestData? = HemoCubeTestData(),
val recommendation: String? = "NA",
val sampleId: String? = "",
val sampleType: String? = "",

View File

@@ -5,7 +5,8 @@ import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData(
@PrimaryKey
@PrimaryKey(autoGenerate = true)
var sampleid: Int = 0,
var _id: String = "",
var name: String = "",
var incubationTime: String = "",

View File

@@ -1,94 +0,0 @@
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,
)

View File

@@ -57,17 +57,3 @@ 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
)

View File

@@ -1,7 +1,7 @@
package com.example.hpostesting.data.repository
import android.net.Uri
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.model.PendingUploads
@@ -20,7 +20,6 @@ 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
@@ -108,37 +107,9 @@ class DatabaseRepository @Inject constructor(
Response.Error(e)
}
}
override suspend fun addTestToDatabaseTrue(data: TrueHemeTestData?): Response<String> {
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<String> {
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) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
TODO("Not yet implemented")
}
override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
@@ -263,4 +234,22 @@ class DatabaseRepository @Inject constructor(
override fun <UserData> addTestToDatabase(testDetails: UserData): Any {
TODO("Not yet implemented")
}
override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> {
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) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
}

View File

@@ -1,6 +1,6 @@
package com.example.hpostesting.data.repository
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -16,7 +16,6 @@ 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
@@ -26,7 +25,7 @@ import okhttp3.ResponseBody
interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabaseTrue(data: TrueHemeTestData?): Response<String>
suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String>

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.domain.di
package com.example.hpostesting.di
import android.app.Application
import android.content.Context
@@ -7,11 +7,10 @@ import android.content.res.AssetManager
import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.api.PropertyProvider
import com.example.hpostesting.util.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
@@ -23,8 +22,8 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.UsbServiceListenerImpl
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module
import dagger.Provides
@@ -62,12 +61,6 @@ object AppModule {
return myDatabase.hemoCubeDao()
}
@Provides
@Singleton
fun provideMyTrueHeme(myDatabase: MyDatabase): TrueHemeDao {
return myDatabase.trueHemeDao()
}
@Provides
@Singleton
fun provideMyHemoCubeBuffer(myDatabase: MyDatabase): HemoCubeBufferDao {
@@ -154,7 +147,7 @@ object AppModule {
@Provides
@Singleton
fun provideRetrofit(
propertyProvider: PropertyProvider,@Named("Auth") client: OkHttpClient
propertyProvider: PropertyProvider, @Named("Auth") client: OkHttpClient
): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build()

View File

@@ -0,0 +1,42 @@
package com.example.hpostesting.encryption
import android.util.Base64
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
object Encryption {
private const val AES_MODE = "AES/CBC/PKCS5Padding"
private const val KEY_SPEC_ALGORITHM = "PBKDF2WithHmacSHA1"
private const val SALT = "Bigtec"
private const val ITERATION_COUNT = 10000
private const val KEY_LENGTH = 256
private val FIXED_IV = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
fun encrypt(textToEncrypt: String, password: String): String {
val salt = SALT.toByteArray()
val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM)
val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH)
val tmp = factory.generateSecret(spec)
val key = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(FIXED_IV))
val encryptedBytes = cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8))
return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP)
}
fun decrypt(encryptedText: String, password: String): String {
val salt = SALT.toByteArray()
val encryptedBytes = Base64.decode(encryptedText, Base64.NO_WRAP)
val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM)
val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH)
val tmp = factory.generateSecret(spec)
val key = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(FIXED_IV))
val decryptedBytes = cipher.doFinal(encryptedBytes)
return String(decryptedBytes, Charsets.UTF_8)
}
}

View File

@@ -10,13 +10,12 @@ import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
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
@@ -297,7 +296,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
}
Constants.DEVICE_TYPE_TRUEHEME -> {
val i = Intent(applicationContext, TrueHemeActivity::class.java)
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
}

View File

@@ -17,7 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData

View File

@@ -1,7 +0,0 @@
package com.example.hpostesting.presentation
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
}

View File

@@ -13,7 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.util.MyUtils

View File

@@ -11,10 +11,9 @@ import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.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
@@ -30,15 +29,15 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
RecyclerView.ViewHolder(binding.root) {
}
private val differCallback = object : DiffUtil.ItemCallback<TrueHemeTestData>() {
private val differCallback = object : DiffUtil.ItemCallback<HemoCubeTestData>() {
override fun areItemsTheSame(
oldItem: TrueHemeTestData, newItem: TrueHemeTestData,
oldItem: HemoCubeTestData, newItem: HemoCubeTestData,
): Boolean {
return oldItem._id == newItem._id
}
override fun areContentsTheSame(
oldItem: TrueHemeTestData, newItem: TrueHemeTestData,
oldItem: HemoCubeTestData, newItem: HemoCubeTestData,
): Boolean {
return oldItem == newItem
}

View File

@@ -14,7 +14,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
@@ -30,7 +30,7 @@ import java.util.Locale
class UserListAdapter(
private val context: Context,
// private val hemoCubeViewModel: HemoCubeViewModel,
private val hemoCubeViewModel: HemoCubeViewModel,
options: FirestoreRecyclerOptions<UserData>,
private val view: View,
private val batLevel: Int,

View File

@@ -14,10 +14,10 @@ import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.trueheme.TrueHemeActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import `in`.sminnovations.hpostesting.databinding.FragmentAssuranceControlsBinding
import java.time.Instant
@@ -178,7 +178,7 @@ class AssuranceControlsFragment : Fragment() {
apply()
}
val i = Intent(requireContext(), TrueHemeActivity::class.java)
val i = Intent(requireContext(), HemocubeActivity::class.java)
startActivity(i)
}
}

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -12,10 +12,9 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
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.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding
@@ -86,8 +85,8 @@ class AutoDacFragment : Fragment() {
private fun getDeviceId() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
@@ -105,8 +104,8 @@ class AutoDacFragment : Fragment() {
private fun runAutoDacCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.AUTO_DAC_COMMAND,
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.AUTO_DAC_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
@@ -119,8 +118,8 @@ class AutoDacFragment : Fragment() {
private fun setAutoDacValuesCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND,
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
@@ -133,8 +132,8 @@ class AutoDacFragment : Fragment() {
private fun readCurrentDACValuesCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.READ_DAC_COMMAND,
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.READ_DAC_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankActivity {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankFragment {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankViewModel {
}

View File

@@ -13,12 +13,11 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
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.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.trueheme.TrueHemeViewModel
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R
@@ -32,7 +31,7 @@ import kotlin.math.log10
class HemoCubeBufferCheckFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val trueViewModel: TrueHemeViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
@@ -111,13 +110,13 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
private fun observeViewModel() {
trueViewModel.deviceData.observe(viewLifecycleOwner) {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
trueViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) {
trueViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
} else {
Toast.makeText(
requireContext(), R.string.internt_not, Toast.LENGTH_SHORT
@@ -125,7 +124,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
isOnline = isNetworkAvailable
}
trueViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast(R.string.kit_uploaded)
}
@@ -140,11 +139,11 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.progressBar.visibility = View.GONE
}
trueViewModel.messages.observe(viewLifecycleOwner) {
hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
trueViewModel.deviceMessages.observe(viewLifecycleOwner) {
hemoCubeViewModel.deviceMessages.observe(viewLifecycleOwner) {
binding.tvDeviceMessages.text = it
}
}
@@ -180,7 +179,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
resultData += stringData
trueViewModel.deviceMessages.postValue(resultData)
hemoCubeViewModel.deviceMessages.postValue(resultData)
when {
stringData.contains("SN") -> {
@@ -197,11 +196,11 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.tvSubtitle4.visibility = View.VISIBLE
binding.btnPlacebuffer.visibility = View.VISIBLE
}
trueViewModel.messages.postValue("Start")
hemoCubeViewModel.messages.postValue("Start")
}
stringData.contains("#BS") -> {
trueViewModel.messages.postValue("Buffer Started")
hemoCubeViewModel.messages.postValue("Buffer Started")
}
stringData.contains("#BC") -> {
@@ -220,7 +219,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
stringData.contains("#SC") -> {
trueViewModel.messages.postValue("Sample Completed \nGathering data")
hemoCubeViewModel.messages.postValue("Sample Completed \nGathering data")
fetchResult()
}
@@ -339,7 +338,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
val prdClassification = absorbanceBasedClassification(_predictedDenovixRatio)
trueViewModel.messages.postValue(prdClassification)
hemoCubeViewModel.messages.postValue(prdClassification)
val bufferData = BufferCheckData(
_id = UUID.randomUUID().toString(),
@@ -373,15 +372,15 @@ class HemoCubeBufferCheckFragment : Fragment() {
testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time),
batteryLevel = trueViewModel.getBatteryLevel().toString(),
batteryCapacity = trueViewModel.getBatteryCapacity(requireContext()).toString(),
batteryMaxCapacity = trueViewModel.getBatteryMaxCapacity(requireContext())
batteryLevel = hemoCubeViewModel.getBatteryLevel().toString(),
batteryCapacity = hemoCubeViewModel.getBatteryCapacity(requireContext()).toString(),
batteryMaxCapacity = hemoCubeViewModel.getBatteryMaxCapacity(requireContext())
.toString(),
batteryTemperature = trueViewModel.getBatteryTemperature().toString(),
batteryVoltage = trueViewModel.getBatteryVoltage(requireContext()).toString()
batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString(),
batteryVoltage = hemoCubeViewModel.getBatteryVoltage(requireContext()).toString()
)
trueViewModel.uploadTrueHemeResultToDatabaseForBufferCheck(isOnline, bufferData)
hemoCubeViewModel.uploadHemoCubeResultToDatabaseForBufferCheck(isOnline, bufferData)
} catch (e: Exception) {
Toast.makeText(
requireContext(), "Error while processing device data", Toast.LENGTH_SHORT
@@ -392,7 +391,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
private fun findResult(calculatedRatio: Double?): String {
try {
trueViewModel.messages.postValue("result classification")
hemoCubeViewModel.messages.postValue("result classification")
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"
@@ -414,7 +413,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String {
try {
trueViewModel.messages.postValue("result classification")
hemoCubeViewModel.messages.postValue("result classification")
if (predictedDenovixRatio != null) {
if (predictedDenovixRatio in 0.0..0.16) return "Kit Passed"
if (predictedDenovixRatio in 0.16..0.165) return "Kit Passed"
@@ -446,7 +445,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_BUFFER_COMMAND,
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_BUFFER_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
@@ -460,7 +459,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_SAMPLE,
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_SAMPLE,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
@@ -470,27 +469,27 @@ class HemoCubeBufferCheckFragment : Fragment() {
}
private fun getDeviceInfo() {
trueViewModel.progressBar.postValue(true)
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
trueViewModel.messages.postValue(stringData)
hemoCubeViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
trueViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.PRINT_COMMAND,
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -15,10 +15,9 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
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.calibration.CalibrationData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
@@ -216,8 +215,8 @@ class CalibrationFragment : Fragment() {
private fun getDeviceId() {
calibrationViewModel.progressBar.postValue(true)
(activity as CalibrationActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
(activity as CalibrationActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {

View File

@@ -0,0 +1,59 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
class ActivitiesFragment : Fragment() {
private lateinit var binding: FragmentActivitiesBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var adapter: OfflineUserListAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentActivitiesBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
hemoCubeViewModel.allPendingUserToUpload.observe(viewLifecycleOwner) { userData ->
if (userData.isNotEmpty()) {
binding.rvOrderOffline.visibility = View.VISIBLE
binding.noDataText.visibility = View.GONE
val bm =
requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel)
adapter.differ.submitList(userData)
binding.rvOrderOffline.adapter = adapter
}else{
binding.rvOrderOffline.visibility = View.GONE
binding.noDataText.visibility = View.VISIBLE
Log.d("Activities","Nothing to show")
}
}
}
}

View File

@@ -1,11 +1,10 @@
package com.example.hpostesting.presentation.dashboard
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -21,24 +20,21 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.NatsManager
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.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
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import okhttp3.ResponseBody
import java.io.File
interface NatsMessageCallback {
@@ -62,8 +58,8 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
lateinit var nats: NatsManager
private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel
private val truehemeViewModel: TrueHemeViewModel by viewModels()
private val hemocubeViewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
@@ -76,6 +72,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
Log.d(TAG, "Received message on topic $topic: $message")
}
@SuppressLint("SetWorldReadable")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -87,25 +84,35 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.connect()
}
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]"
binding.appBarDashboard.versionName.text = versionName
val deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
nats.sub("server.hpos.${deviceId}.ping")
nats.pub("server.hpos.${deviceId}.ping", "THIS IS A TEST MSG")
truehemeViewModel.deviceUpdate.observe(this) { result ->
hemocubeViewModel.deviceUpdate.observe(this) { result ->
when (result) {
is Result.Success -> {
// Handle success
val apkUrl = result.data
// val apkUrl = "https://dl.dropboxusercontent.com/s/fi/1c3nn7t0co431hicl3hrt/app-debug.apk?rlkey=e4uf13ty1dpcked614vy1aaqp&dl=0"
initiateUpdate(apkUrl.toString())
Log.d("ApI", "APK URL: $apkUrl")
// Toast.makeText(
// this,
// "APK UPLOAD ${result.data}",
// Toast.LENGTH_SHORT
// ).show()
val apk = result.data
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
apk.byteStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
Log.d("Responsebodyformat", "Responsebodyformat: ")
installApk(file)
Log.e("ApI", "APK URL: $apk")
Toast.makeText(
this,
"${result.data}",
Toast.LENGTH_SHORT
).show()
}
is Result.Error -> {
@@ -130,7 +137,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_profile, R.id.nav_settings
R.id.nav_home, R.id.nav_profile, R.id.nav_activity,R.id.nav_settings
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
@@ -155,56 +162,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private fun initiateUpdate(url: String) {
val apkUrl = url
if (!isValidHttpUrl(apkUrl)) {
return
}
val request = DownloadManager.Request(Uri.parse(apkUrl))
request.setTitle("App Update")
request.setDescription("Downloading update...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(this, "Updates", "update.apk")
val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
isRegistered = true
registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED)
}
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
}
private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://")
}
private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId) {
installApk()
}
}
}
private fun installApk() {
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
private fun installApk(file: File) {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile(
this,
"in.sminnovations.hpostesting.dev.fileprovider",
"${BuildConfig.APPLICATION_ID}.fileprovider",
file
)
// Create an intent to install the APK
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri
installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
@@ -222,7 +188,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun onDestroy() {
if(isRegistered) {
try {
unregisterReceiver(downloadReceiver)
// unregisterReceiver(downloadReceiver)
} catch (e: Exception) {
Log.d("HomeFragment", e.toString())
}
@@ -279,6 +245,30 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun setResponse(response: String) {
responses = responses+response+"\n"
println(responses)
Log.d("DashBoardActResponse",response)
// if (response.contains("checkUpdate")) {
// hemocubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
// }
}
private fun createDeviceUpdateRequestData(): DeviceUpdateRequest {
return DeviceUpdateRequest(
serial_no = sharedPreference.getString(Constants.DEVICE_ID, "")
)
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
private fun getAppEnvironment(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.packageName.substringAfterLast('.')
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
}

View File

@@ -21,13 +21,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.DataHolder
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.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -183,9 +182,9 @@ class DeviceActivity : AppCompatActivity(), DeviceCommunicationHandler {
}
}
override fun sendAndListenToDevice(command: TrueHemeCommands, listener: UsbServiceListener) {
mService.sendAndListenToTrueHeme(
command = TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) {
mService.sendAndListenToHemoCube(
command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
listener
)
}

View File

@@ -12,8 +12,7 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
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.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
@@ -49,8 +48,8 @@ class DeviceFragment : Fragment() {
private fun getDeviceId() {
deviceViewModel.progressBar.postValue(true)
(activity as DeviceActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
(activity as DeviceActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
@SuppressLint("SetTextI18n")
override fun onUsbRead(data: ByteArray?) {

View File

@@ -20,13 +20,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.DataHolder
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.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -186,9 +185,9 @@ class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler
}
}
override fun sendAndListenToDevice(command: TrueHemeCommands, listener: UsbServiceListener) {
mService.sendAndListenToTrueHeme(
command = TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) {
mService.sendAndListenToHemoCube(
command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
listener
)
}

View File

@@ -4,6 +4,8 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -12,17 +14,20 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.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
import com.example.hpostesting.encryption.Encryption
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
import java.io.File
import java.io.FileOutputStream
class DeviceProvisionFragment : Fragment() {
private var resultData: String = ""
@@ -123,6 +128,10 @@ class DeviceProvisionFragment : Fragment() {
deviceUpdateAvailable = false
)
)
encryptAndSaveToFile(
response.data.data?.credentials?.username.toString(),
response.data.data?.credentials?.password.toString()
)
// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()))
Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString())
@@ -167,8 +176,8 @@ class DeviceProvisionFragment : Fragment() {
}
private fun getDeviceId() {
(activity as DeviceProvisionActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
(activity as DeviceProvisionActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {}
@@ -222,4 +231,25 @@ class DeviceProvisionFragment : Fragment() {
}
}
}
}
private fun encryptAndSaveToFile(username: String, password: String) {
val messageToEncrypt = "$username\n$password"
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey)
Log.d("DEVICE ID/encryptionKey", encryptionKey)
val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File(target, "credentials.txt")
if (!file.exists()) {
file.createNewFile()
}
file.writeText(encryptedString)
Log.d("Encrypted Message", encryptedString)
}
}

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.deviceprovision
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -13,16 +13,15 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.Result.Success
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
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.devicediagnostics.AdditionalDetails
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding
@@ -149,8 +148,8 @@ class DiagnosticsFragment : Fragment() {
private fun getDeviceId() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
@@ -168,8 +167,8 @@ class DiagnosticsFragment : Fragment() {
private fun runDeviceDiagnostics() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DIAGNOSTICS_COMMAND,
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DIAGNOSTICS_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.diagnostics
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -25,7 +25,7 @@ class DiagnosticsViewModel @Inject constructor(
val deviceData = MutableLiveData<DeviceData?>()
val fireBaseUpload = MutableLiveData<String>()
val deviceDiagnosticsResponse = MutableLiveData<com.example.hpostesting.data.Result<DeviceDiagnosticsResponse>>()
val deviceDiagnosticsResponse = MutableLiveData<Result<DeviceDiagnosticsResponse>>()
// private val batteryStatus: Intent? =
// IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
// context.registerReceiver(null, ifilter)

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding
import java.text.SimpleDateFormat

View File

@@ -1,79 +1,342 @@
package com.example.hpostesting.presentation.hemocube
import android.content.Context
import android.content.SharedPreferences
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.util.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
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.repository.DatabaseRepository
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 dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
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 trueHemeDao: TrueHemeDao,
private val repository: DatabaseRepository,
private val hemoCubeBufferDao: HemoCubeBufferDao,
private val repository: Repository,
private val logFileManager: LogFileManager,
private val localFileDataSource: LocalFileDataSource,
context: Context,
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences =
context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
private val sharedPreference =
context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
private val workManager = WorkManager.getInstance(context)
// init {
// startPeriodicCheckUpdate()
// }
val loginResponse = MutableLiveData<Result<LoginResponse>>()
val resultUpload = MutableLiveData<Result<MolbioV2ResultResponse>>()
val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>()
val deviceUpdate = MutableLiveData<Result<ResponseBody>>()
val downloadcertificate = MutableLiveData<Result<ResponseBody>>()
val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>()
// 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 = trueHemeDao.getAll()
val allUserData = hemoCubeDao.getAll()
val allLocalData = hemoCubeDao.getAll()
val allPendingUserToUpload = hemoCubeDao.getPendingUser()
val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val deviceMessages = MutableLiveData<String?>()
val fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
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")
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 uploadResultfornew(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
}
fun sendDataToMolbio() = viewModelScope.launch(Dispatchers.IO) {
Log.d("molbio","getting in sendMolbio")
val resultList = MolbioV2ResultRequest(mutableListOf())
val pendingData = hemoCubeDao.getMolbioPending()
Log.d("molbio","pending size"+pendingData.size)
pendingData.forEach{
userData ->
val currentTimeFormatted = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
Locale.getDefault()
).format(Calendar.getInstance().time)
val bufferIntensityThreshold =
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult
?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult
?: "defaultInterpretation", // Handle possible nulls
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
)
)
}
resultList.results?.forEach { result ->
result.rawData?.let { sanitizeDoubleValues(it) }
}
if (resultList.results?.isNotEmpty() == true) {
uploadMoblioBulkResults(resultList)
}
}
fun uploadMoblioBulkResults(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
Log.d("molbio","upload called")
repository.uploadResults(molbioV2ResultRequest).let {
when (it) {
is Result.Success -> {
it.data.data?.forEach { id ->
id.rawData?.let { it1 ->
updateMolbioFlag(
it1._id
)
}
}
}
is Result.Error -> {
Log.d("result","result upload error")
}
else -> {
Log.d("result","result upload else")
}
}
}
}
fun sendDataToFirebase() = viewModelScope.launch ( Dispatchers.IO ) {
val pendingData = hemoCubeDao.getFirebasePending()
pendingData.forEach{
userData ->
if (userData != null) {
if (!userData.localFlag) {
bulkAddResultTestToDb(userData)
}
} catch (e: Exception) {
Log.e("Testdb", "Upload failed: ${e.message}")
}
}
}
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<CheckUpdateWorker>(
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 getPendingUser() = viewModelScope.launch {
// allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(true))
// }
fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean,
bufferCheckData: BufferCheckData,
) =
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)
}
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")
}
} else {
hemoCubeBufferDao.insertAll(bufferCheckData)
fireBaseUpload.postValue("Local")
}
}
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 {
addResultTestToDbforbuffercheck(bufferCheckData)
@@ -83,7 +346,7 @@ class HemoCubeViewModel @Inject constructor(
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun parseData() {
fun parseData() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
@@ -97,14 +360,44 @@ 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() {
@@ -124,6 +417,30 @@ class HemoCubeViewModel @Inject constructor(
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
// Now, use sanitizedTestDetails for the API call
uploadResult(
MolbioV2ResultRequest(
mutableListOf(
MolbioV2Result(
rawData = sanitizedTestDetails,
analysisId = sanitizedTestDetails._id,
analysisDate = sanitizedTestDetails.testTime,
analysisStatus = sanitizedTestDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(),
interpretation = sanitizedTestDetails.classificationResult,
testId = sanitizedTestDetails._id,
testTime = sanitizedTestDetails.testTime,
collectionTime = sanitizedTestDetails.testTime,
expiryTime = sanitizedTestDetails.testTime,
)
)
)
)
}
hemoCubeDao.insertAll(testDetails)
}
@@ -132,29 +449,8 @@ 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")
}
}
}
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}")
@@ -181,11 +477,184 @@ class HemoCubeViewModel @Inject constructor(
}
}
fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData {
hemoCubeTestData::class.java.declaredFields.forEach { field ->
if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) {
field.isAccessible = true
val value = field.get(hemoCubeTestData) as Double?
if (value != null && (value.isInfinite() || value.isNaN())) {
field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value
}
}
}
return hemoCubeTestData
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
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<List<HemoCubeTestData>> = hemoCubeDao.getAll()
// Observe the LiveData to get the actual data when available
localUserDataLiveData.observeForever { localUserData ->
localUserData?.let {
val csvData = mutableListOf<Array<String>>()
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<HemoCubeTestData>, 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)
}
}

View File

@@ -1,5 +1,6 @@
package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
@@ -10,17 +11,20 @@ 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
import android.view.Menu
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.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
@@ -41,6 +45,7 @@ open class HemocubeActivity : AppCompatActivity() {
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
@@ -59,6 +64,7 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
@@ -73,6 +79,13 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
@@ -97,6 +110,7 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.O)
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -116,12 +130,13 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.O)
@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_IMMUTABLE
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
@@ -133,15 +148,21 @@ open class HemocubeActivity : AppCompatActivity() {
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(broadcastReceiver, filter, RECEIVER_EXPORTED)
}else{
registerReceiver(broadcastReceiver, filter)
}
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
@RequiresApi(Build.VERSION_CODES.O)
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)
@@ -166,7 +187,6 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()

View File

@@ -21,7 +21,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -19,7 +19,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -132,7 +132,7 @@ class TestRightActivity : AppCompatActivity() {
this,
0,
Intent(Constants.ACTION_USB_PERMISSION),
PendingIntent.FLAG_MUTABLE
PendingIntent.FLAG_IMMUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(

View File

@@ -10,11 +10,11 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -10,13 +10,13 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.MainActivity
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -11,7 +11,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.data.model.test.TestType

View File

@@ -5,8 +5,8 @@ import android.net.Uri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest

View File

@@ -9,8 +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.example.hpostesting.presentation.utils.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager
@@ -101,14 +100,7 @@ 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
@@ -117,12 +109,4 @@ 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)
}
}
}

View File

@@ -11,7 +11,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
@@ -21,27 +20,29 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.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.ActivityTruehemeBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
@AndroidEntryPoint
open class TrueHemeActivity : AppCompatActivity() {
private lateinit var binding: ActivityTruehemeBinding
private val viewModel by viewModels<TrueHemeViewModel>()
class TrueHemeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "TrueHeme"
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -62,7 +63,6 @@ open class TrueHemeActivity : AppCompatActivity() {
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
@@ -83,9 +83,10 @@ open class TrueHemeActivity : AppCompatActivity() {
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTruehemeBinding.inflate(layoutInflater)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
@@ -95,7 +96,7 @@ open class TrueHemeActivity : AppCompatActivity() {
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "TrueHeme called -> $it")
Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it) {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
@@ -126,28 +127,25 @@ open class TrueHemeActivity : AppCompatActivity() {
}
}
@SuppressLint("MutableImplicitPendingIntent")
@SuppressLint("MutableImplicitPendingIntent", "UnspecifiedRegisterReceiverFlag")
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.TRUEHEME_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
this,
0,
Intent(Constants.TRUEHEME_USB_PERMISSION),
Intent(Constants.HEMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
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)
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
@@ -166,20 +164,21 @@ open class TrueHemeActivity : AppCompatActivity() {
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fgTrueheme.id, TrueHemeFragment())
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment())
.commit()
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fg_trueheme)
if (fragment is TrueHemeFragment) {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) {
fragment.handleBackButtonPress()
} else {
super.onBackPressed()
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -13,17 +14,17 @@ 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.DataHolder
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TrueHemeCommands
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestStateTrueHeme
import com.example.hpostesting.data.model.TestState
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toTrueHemeTestData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.trueheme.TrueHemeActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics
@@ -34,12 +35,13 @@ import kotlin.math.abs
import kotlin.math.log10
@Suppress("MemberVisibilityCanBePrivate")
@SuppressLint("SetTextI18n")
class TrueHemeFragment : Fragment() {
private lateinit var binding: FragmentTruehemeSampleBinding
private val trueHemeViewModel: TrueHemeViewModel by activityViewModels()
private val hemoCubeViewModel: TrueHemeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private val testDetails = DataHolder.selectedTest?.toTrueHemeTestData()
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
private var isOnline = false
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
@@ -68,17 +70,17 @@ class TrueHemeFragment : Fragment() {
private var readingsPerSample = Constants.READINGS_PER_SAMPLE
private var uploadedToCloud = false
private var uploadedToMolbio = false
lateinit var testState: TestStateTrueHeme
lateinit var testState: TestState
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentTruehemeSampleBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("TRUEHEME", Context.MODE_PRIVATE)
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
testState = TestStateTrueHeme(
testDetails = DataHolder.selectedTest?.toTrueHemeTestData(),
testState = TestState(
testDetails = DataHolder.selectedTest?.toHemoCubeTestData(),
)
return binding.root
@@ -87,21 +89,18 @@ class TrueHemeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
listenToTrueHeme()
listenToHemoCube()
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
}
trueHemeViewModel.uploadTrueHemeResultToDatabase(
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
}
@@ -111,6 +110,8 @@ 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,6 +138,7 @@ class TrueHemeFragment : Fragment() {
checkAndStartProcess()
it.visibility = View.GONE
}
}
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
@@ -147,42 +149,40 @@ class TrueHemeFragment : Fragment() {
}
private fun observeViewModel() {
trueHemeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
uploadedToCloud = true
showToast(R.string.test_upload)
if (Constants.MOLBIO_INTEGRATION) {
trueHemeViewModel.resultUpload.observe(viewLifecycleOwner) {
when (it) {
is Result.Success -> {
uploadedToMolbio = true
hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) {
when (it) {
is Result.Success -> {
uploadedToMolbio = true
if (Constants.MOLBIO_INTEGRATION) {
it.data.data?.get(0)?.rawData?.let { it1 ->
trueHemeViewModel.updateMolbioFlag(
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 -> {}
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()
}
}
if (result == "Local") {
@@ -197,15 +197,15 @@ class TrueHemeFragment : Fragment() {
binding.progressBar.visibility = View.GONE
}
trueHemeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
trueHemeViewModel.deviceData.observe(viewLifecycleOwner) {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
trueHemeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
DataHolder.trueHemeTestData?.let {
DataHolder.hemoCubeTestData?.let {
currentDeviceData?.coefficients?.let { coefficients ->
// val coefficient1 = coefficients[0]
// val coefficient2 = coefficients[1]
@@ -216,21 +216,17 @@ class TrueHemeFragment : Fragment() {
}
}
trueHemeViewModel.messages.observe(viewLifecycleOwner) {
hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
trueHemeViewModel.deviceMessages.observe(viewLifecycleOwner) {
hemoCubeViewModel.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(
@@ -239,7 +235,7 @@ class TrueHemeFragment : Fragment() {
startActivity(i)
}
} else {
trueHemeViewModel.messages.postValue("Reading $repeatReadingCount completed")
hemoCubeViewModel.messages.postValue("Reading $repeatReadingCount completed")
resetTest()
startSampleProcess()
}
@@ -319,15 +315,15 @@ class TrueHemeFragment : Fragment() {
})
}
private fun listenToTrueHeme() {
DataHolder.trueHemeTestData = DataHolder.selectedTest?.toTrueHemeTestData()
trueHemeViewModel.progressBar.postValue(true)
private fun listenToHemoCube() {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as TrueHemeActivity).mService.listenToTrueHeme(object : UsbServiceListener {
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
@@ -337,7 +333,7 @@ class TrueHemeFragment : Fragment() {
}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
@@ -347,34 +343,20 @@ class TrueHemeFragment : Fragment() {
}
private fun getDeviceInfo() {
trueHemeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(
TrueHemeCommands.DEVICE_CONFIGURATION_COMMAND,
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)
trueHemeViewModel.messages.postValue(stringData)
hemoCubeViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
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)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
@@ -386,12 +368,11 @@ class TrueHemeFragment : Fragment() {
resultData += stringData
currentResultData += stringData
trueHemeViewModel.deviceMessages.postValue(currentResultData)
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 -> {
@@ -401,24 +382,18 @@ 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
trueHemeViewModel.messages.postValue("Air reading started")
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
trueHemeViewModel.messages.postValue("Air reading completed")
hemoCubeViewModel.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 -> {
trueHemeViewModel.messages.postValue(getString(R.string.buffer_started))
hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started))
this.testStatusCode = TestStatus.BUFFER_STARTED.code
}
@@ -440,7 +415,7 @@ class TrueHemeFragment : Fragment() {
(resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> {
this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code
trueHemeViewModel.messages.postValue(
hemoCubeViewModel.messages.postValue(
getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data)
)
fetchResult()
@@ -448,54 +423,54 @@ class TrueHemeFragment : Fragment() {
}
resultData.contains("ovf") -> {
trueHemeViewModel.messages.postValue(
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
trueHemeViewModel.messages.postValue("1.3X Gain Started")
hemoCubeViewModel.messages.postValue("1.3X Gain Started")
}
currentResultData.contains("#SC2") && this.testStatusCode < TestStatus.FIRST_GAIN_COMPLETED.code -> {
this.testStatusCode = TestStatus.FIRST_GAIN_COMPLETED.code
trueHemeViewModel.messages.postValue("1.3X Gain Completed")
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
trueHemeViewModel.messages.postValue("2X Gain Started")
hemoCubeViewModel.messages.postValue("2X Gain Started")
}
currentResultData.contains("#SC3") && this.testStatusCode < TestStatus.SECOND_GAIN_COMPLETED.code -> {
this.testStatusCode = TestStatus.SECOND_GAIN_COMPLETED.code
trueHemeViewModel.messages.postValue("2X Gain Completed")
hemoCubeViewModel.messages.postValue("2X Gain Completed")
fetchResult()
}
currentResultData.contains("#SS5") && this.testStatusCode < TestStatus.FORTH_GAIN_STARTED.code -> {
this.testStatusCode = TestStatus.FORTH_GAIN_STARTED.code
trueHemeViewModel.messages.postValue("7.6X Gain Started")
hemoCubeViewModel.messages.postValue("7.6X Gain Started")
}
currentResultData.contains("#SC5") && this.testStatusCode < TestStatus.FORTH_GAIN_COMPLETED.code -> {
this.testStatusCode = TestStatus.FORTH_GAIN_COMPLETED.code
trueHemeViewModel.messages.postValue("7.6X Gain Completed")
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
trueHemeViewModel.messages.postValue("Air reading started")
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
trueHemeViewModel.messages.postValue("Air reading completed")
hemoCubeViewModel.messages.postValue("Air reading completed")
fetchResult()
}
@@ -507,10 +482,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
trueHemeViewModel.messages.postValue("First air reading completed")
hemoCubeViewModel.messages.postValue("First air reading completed")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.trueHemeTestData?.apply {
DataHolder.hemoCubeTestData?.apply {
led1Air1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Air1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Air1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
@@ -525,10 +500,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
trueHemeViewModel.messages.postValue("Second air reading completed")
hemoCubeViewModel.messages.postValue("Second air reading completed")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.trueHemeTestData?.apply {
DataHolder.hemoCubeTestData?.apply {
led1Air2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Air2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Air2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
@@ -543,10 +518,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
trueHemeViewModel.messages.postValue("1.3X gain data gathered")
hemoCubeViewModel.messages.postValue("1.3X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.trueHemeTestData?.apply {
DataHolder.hemoCubeTestData?.apply {
led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
@@ -562,10 +537,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
trueHemeViewModel.messages.postValue("2X gain data gathered")
hemoCubeViewModel.messages.postValue("2X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.trueHemeTestData?.apply {
DataHolder.hemoCubeTestData?.apply {
led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
@@ -581,14 +556,15 @@ 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
trueHemeViewModel.messages.postValue("7.6X gain data gathered")
hemoCubeViewModel.messages.postValue("7.6X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.trueHemeTestData?.apply {
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()!!
led4Gain4 =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
}
finishReading()
@@ -598,7 +574,6 @@ class TrueHemeFragment : Fragment() {
fun finishReading() {
repeatReadingCount += 1
isTestOngoing = false
if (readingsPerSample == 1) {
activity?.runOnUiThread {
@@ -609,7 +584,7 @@ class TrueHemeFragment : Fragment() {
binding.ivCheck.visibility = View.VISIBLE
}
} else {
trueHemeViewModel.uploadTrueHemeResultToDatabase(
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
}
@@ -618,7 +593,7 @@ class TrueHemeFragment : Fragment() {
fun handleSampleCompleted() {
this.testStatusCode = TestStatus.SAMPLE_PRINT_COMPLETED.code
trueHemeViewModel.messages.postValue(
hemoCubeViewModel.messages.postValue(
getString(R.string.data_collected_processing_data)
)
@@ -667,26 +642,23 @@ class TrueHemeFragment : Fragment() {
if (!hardwareId.isNullOrBlank()) {
updateDeviceId(hardwareId)
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE
}
hemoCubeViewModel.messages.postValue(getString(R.string.start))
} else {
trueHemeViewModel.messages.postValue("Config error")
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"
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)
@@ -699,12 +671,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 {
trueHemeViewModel.messages.postValue("Config error")
hemoCubeViewModel.messages.postValue("Config error")
}
if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) {
@@ -719,10 +691,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? {
@@ -753,7 +725,7 @@ class TrueHemeFragment : Fragment() {
private fun processResult() {
try {
trueHemeViewModel.messages.postValue(getString(R.string.processing_result))
hemoCubeViewModel.messages.postValue(getString(R.string.processing_result))
val deviceLog = resultData
val pInfo = requireActivity().packageManager.getPackageInfo(
@@ -765,8 +737,7 @@ class TrueHemeFragment : Fragment() {
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
val deviceRatio = led4Average / led1Average
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!!
@@ -780,10 +751,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
}
}
@@ -800,12 +771,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
}
}
@@ -843,46 +814,46 @@ class TrueHemeFragment : Fragment() {
calculatedPredictedDenovixRatio = fittedAbs3.div(fittedAbs1)
val slope = (led4Average - led1Average) / (431 - 411)
val calculatedSlopeRatio = abs(led2Average / slope)
val slope = (led1Average - led2Average) / (435 - 415)
val calculatedSlopeRatio = abs(led3Average / 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
}
}
val absorbanceLowerLimit = 0.0
if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) {
if ((led1Average < 0.7 || led2Average < 0.7 || led3Average < 0.7 || led4Average < 0.7) && calculatedSlopeRatio > 35.0) {
validationError = true
activity?.runOnUiThread {
binding.errorMessage.text = "Invalid"
binding.errorMessage.text =
"Severely Low Hb. Repeat test with 12 ul in 2 ml Buffer"
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.trueHemeTestData?.apply {
DataHolder.hemoCubeTestData?.apply {
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()
led1Buffer = led1BufferForDevice
led2Buffer = led2BufferForDevice
@@ -911,32 +882,21 @@ 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 = 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.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.errorMessages = testState.allErrorMessages
this.resultData = deviceLog
this.batteryLevel = trueHemeViewModel.getBatteryLevel().toString()
this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString()
this.batteryCapacity =
trueHemeViewModel.getBatteryCapacity(requireContext()).toString()
hemoCubeViewModel.getBatteryCapacity(requireContext()).toString()
this.batteryMaxCapacity =
trueHemeViewModel.getBatteryMaxCapacity(requireContext()).toString()
this.batteryTemperature = trueHemeViewModel.getBatteryTemperature().toString()
hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString()
this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString()
this.batteryVoltage =
trueHemeViewModel.getBatteryVoltage(requireContext()).toString()
hemoCubeViewModel.getBatteryVoltage(requireContext()).toString()
}
if (!isUsingExistingBuffer) {
@@ -958,97 +918,50 @@ class TrueHemeFragment : Fragment() {
}
}
fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String {
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"
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 (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)
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"
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 "Invalid"
return getString(R.string.invalid)
}
} catch (e: Exception) {
handleException(e)
return "Error"
showToast(R.string.error_classification)
Firebase.crashlytics.recordException(e)
return getString(R.string.error)
}
return "Invalid"
return getString(R.string.invalid)
}
fun deviceRatioClassification(ratio: Double?): String {
try {
if (ratio != null) {
if (ratio in 0.16..0.23) {
if (ratio in 0.2..0.29) {
// setSubtitleTextColor(R.color.green_2)
return "Normal"
}
if (ratio in 0.23..0.25)
return "Negative Borderline"
if (ratio in 0.25..0.31)
if (ratio in 0.29..0.32)
return "Negative Borderline, Repeat Test"
if (ratio in 0.32..0.35)
return "Sickle Cell Trait"
if (ratio in 0.31..0.36)
if (ratio in 0.35..0.38)
return "Positive for Sickle Cell. HPLC for Confirmation"
if (ratio in 0.36..0.7)
if (ratio in 0.38..0.5)
return "Sickle Cell Disease"
} else {
return "Invalid"
@@ -1073,7 +986,7 @@ class TrueHemeFragment : Fragment() {
fun slopeRatioClassification(ratio: Double?): String {
try {
trueHemeViewModel.messages.postValue("result classification")
hemoCubeViewModel.messages.postValue("result classification")
if (ratio != null) {
if (ratio in 0.0..30.0)
return getString(R.string.normal)
@@ -1098,7 +1011,7 @@ class TrueHemeFragment : Fragment() {
private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String {
try {
trueHemeViewModel.messages.postValue("result classification")
hemoCubeViewModel.messages.postValue("result classification")
if (predictedDenovixRatio != null) {
if (predictedDenovixRatio in 0.0..0.16) {
// activity?.runOnUiThread {
@@ -1135,96 +1048,103 @@ class TrueHemeFragment : Fragment() {
}
private fun startBufferProcess() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_BUFFER_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.START_BUFFER_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun startSampleProcess() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.START_SAMPLE,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.START_SAMPLE,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendFirstGainCommand() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.FIRST_GAIN_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.FIRST_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendSecondGainCommand() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.SECOND_GAIN_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.SECOND_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendThirdGainCommand() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.THIRD_GAIN_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.THIRD_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendForthGainCommand() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.FORTH_GAIN_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.FORTH_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() {
trueHemeViewModel.progressBar.postValue(true)
hemoCubeViewModel.progressBar.postValue(true)
(activity as TrueHemeActivity).mService.sendAndListenToTrueHeme(TrueHemeCommands.PRINT_COMMAND,
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.PRINT_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
trueHemeViewModel.progressBar.postValue(false)
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
@@ -1234,4 +1154,10 @@ class TrueHemeFragment : Fragment() {
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
return coefficient1 * ratio + coefficient2
}
}
private fun reconnect() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
(activity as HemocubeActivity).reconnectDevice()
}
}
}

View File

@@ -12,13 +12,13 @@ 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.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.TrueHemeDao
import com.example.hpostesting.data.dao.HemoCubeDao
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.TrueHemeTestData
import com.example.hpostesting.data.model.patient.toTrueHemeTestData
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
@@ -52,7 +52,7 @@ import javax.inject.Inject
@Suppress("MemberVisibilityCanBePrivate")
@HiltViewModel
class TrueHemeViewModel @Inject constructor(
private val trueHemeDao: TrueHemeDao,
private val hemoCubeDao: HemoCubeDao,
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?.toTrueHemeTestData()
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>()
private val sharedPreference =
context.getSharedPreferences("TRUEHEME", Context.MODE_PRIVATE)
context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
private val workManager = WorkManager.getInstance(context)
@@ -79,20 +79,16 @@ class TrueHemeViewModel @Inject constructor(
val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>()
val deviceUpdate = MutableLiveData<Result<ResponseBody>>()
val downloadcertificate = MutableLiveData<Result<ResponseBody>>()
val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>()
// 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 = trueHemeDao.getAll()
val allPendingUserToUpload = MutableLiveData<List<TrueHemeTestData>>()
val allUserData = hemoCubeDao.getAll()
val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val deviceMessages = MutableLiveData<String?>()
@@ -104,7 +100,7 @@ class TrueHemeViewModel @Inject constructor(
context.registerReceiver(null, ifilter)
}
fun uploadTrueHemeResultToDatabase(
fun uploadHemoCubeResultToDatabase(
isOnline: Boolean, testStatus: Boolean, kitSerial: String?,
) = viewModelScope.launch {
if (kitSerial != null) {
@@ -121,7 +117,7 @@ class TrueHemeViewModel @Inject constructor(
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
trueHemeDao.insertAll(testDetails!!)
hemoCubeDao.insertAll(testDetails!!)
fireBaseUpload.postValue("Local")
}
} catch (e: Exception) {
@@ -157,13 +153,6 @@ class TrueHemeViewModel @Inject constructor(
}
}
fun downloadClientCertificate() = viewModelScope.launch {
downloadcertificate.postValue(Result.Loading())
repository.downloadClientCertificate().let {
downloadcertificate.postValue(it)
}
}
fun startPeriodicCheckUpdate() {
val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>(
repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES
@@ -187,11 +176,8 @@ class TrueHemeViewModel @Inject constructor(
}
}
}
fun uploadPendingUser() = viewModelScope.launch {
allPendingUserToUpload.postValue(trueHemeDao.getPendingUser(false))
}
fun uploadTrueHemeResultToDatabaseForBufferCheck(
fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean,
bufferCheckData: BufferCheckData,
) =
@@ -244,7 +230,7 @@ class TrueHemeViewModel @Inject constructor(
}
}
fun uploadTrueHemeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch {
addResultTestToDbforbuffercheck(bufferCheckData)
}
@@ -254,57 +240,56 @@ class TrueHemeViewModel @Inject constructor(
}
fun parseData() {
testDetails?.deviceRatio = DataHolder.trueHemeResult
testDetails?.resultData = DataHolder.trueHemeTestData?.resultData.toString()
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
testDetails?.appVersion = DataHolder.trueHemeTestData?.appVersion
testDetails?.deviceId = DataHolder.trueHemeTestData?.deviceId
testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion
testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId
testDetails?.deviceSerialNumber =
sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
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
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
}
private fun addResultTestToDb() {
@@ -314,7 +299,7 @@ class TrueHemeViewModel @Inject constructor(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (val response = repository.addTestToDatabaseTrue(testDetails)) {
when (val response = repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
@@ -324,33 +309,31 @@ class TrueHemeViewModel @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,
)
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,
)
)
)
}
trueHemeDao.insertAll(testDetails)
)
hemoCubeDao.insertAll(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
trueHemeDao.insertAll(testDetails)
hemoCubeDao.insertAll(testDetails)
}
else -> {}
@@ -362,12 +345,12 @@ class TrueHemeViewModel @Inject constructor(
}
}
fun bulkAddResultTestToDb(userData: TrueHemeTestData) {
fun bulkAddResultTestToDb(userData: HemoCubeTestData) {
viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabaseTrue(userData)) {
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseBulkUpload.postValue("Success")
updateLocalFlag(userData._id)
@@ -381,22 +364,21 @@ class TrueHemeViewModel @Inject constructor(
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
trueHemeDao.updateFieldById(id = userId, true)
hemoCubeDao.updateFieldById(id = userId, true)
}
fun updateMolbioFlag(userId: String) = viewModelScope.launch {
trueHemeDao.updateMolbioFlag(id = userId, true)
hemoCubeDao.updateMolbioFlag(id = userId, true)
}
fun addUser(userData: TrueHemeTestData) = viewModelScope.launch {
trueHemeDao.insertAll(userData)
fun addUser(userData: HemoCubeTestData) = viewModelScope.launch {
hemoCubeDao.insertAll(userData)
}
fun deleteById(userId: String) = viewModelScope.launch {
trueHemeDao.deleteById(id = userId)
hemoCubeDao.deleteById(id = userId)
}
private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) {
viewModelScope.launch {
try {
@@ -412,8 +394,6 @@ 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}")
@@ -428,7 +408,7 @@ class TrueHemeViewModel @Inject constructor(
}
fun getLocalUserDataForCsv(context: Context): Boolean {
val localUserDataLiveData: LiveData<List<TrueHemeTestData>> = trueHemeDao.getAll()
val localUserDataLiveData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll()
// Observe the LiveData to get the actual data when available
localUserDataLiveData.observeForever { localUserData ->
@@ -528,13 +508,13 @@ class TrueHemeViewModel @Inject constructor(
return maxCapacity
}
fun createCSV(trueHemeTestData: List<TrueHemeTestData>, appContext: Context) =
fun createCSV(hemoCubeTestData: List<HemoCubeTestData>, appContext: Context) =
viewModelScope.launch {
val fileName = "HPOS${getCurrentDate()}.csv"
if (localFileDataSource.exportDataToCSV(fileName, trueHemeTestData)) {
trueHemeTestData.forEach { data ->
if (localFileDataSource.exportDataToCSV(fileName, hemoCubeTestData)) {
hemoCubeTestData.forEach { data ->
data.localFlag = true
trueHemeDao.updateCSVFieldById(
hemoCubeDao.updateCSVFieldById(
data._id,
true
)

View File

@@ -0,0 +1,7 @@
package com.example.hpostesting.presentation.utils
import com.example.hpostesting.data.constant.HemoCubeCommands
interface DeviceCommunicationHandler {
fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener)
}

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
import android.content.Context
import android.os.Build

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
interface UsbServiceListener {
fun onUsbRead(data: ByteArray?)

View File

@@ -1,8 +1,9 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
import android.content.Context
import android.util.Log
import android.widget.Toast
import com.example.hpostesting.presentation.utils.UsbServiceListener
class UsbServiceListenerImpl(private val context: Context): UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {

View File

@@ -1,11 +0,0 @@
package com.example.hpostesting
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
fun main(){
val dateFormat = SimpleDateFormat("MM:HHddMMyyyy", Locale.getDefault())
val currentDate = Date()
print(dateFormat.format(currentDate))
}

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context
import android.os.Environment

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context
import android.content.SharedPreferences

View File

@@ -0,0 +1,7 @@
package com.example.hpostesting.util
interface PropertyProvider {
fun getProperty(key: String): String
}

View File

@@ -1,7 +1,6 @@
package com.example.hpostesting.util
import android.content.res.AssetManager
import com.example.hpostesting.data.api.PropertyProvider
import java.io.InputStream
import java.util.Properties

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>()

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
</vector>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.dashboard.DashboardActivity">
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
@@ -16,7 +16,17 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" />
app:popupTheme="@style/Theme.HPOS.PopupOverlay" >
<TextView
android:id="@+id/version_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textStyle="bold"
android:layout_gravity="end"
android:textSize="18sp"
android:layout_marginEnd="15dp"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Upload Pending List(Local data)"
android:layout_marginTop="5dp"
android:textSize="21sp"
android:textColor="@color/black"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order_offline"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/titleText"
android:layout_alignParentStart="true"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/offline_user_list_view" />
<TextView
android:id="@+id/noDataText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="All up-to-date"
android:textSize="22sp"
android:textColor="@color/black"
/>
</RelativeLayout>

View File

@@ -38,10 +38,20 @@
android:visibility="gone"
android:padding="24dp">
<ImageView
android:id="@+id/btnLogout1"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:src="@drawable/baseline_logout_24"
app:layout_constraintTop_toTopOf="@+id/internetNotAvailableCL"
app:layout_constraintEnd_toEndOf="parent"
/>
<TextView
android:id="@+id/tv_title_no_internet"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="24dp"
@@ -125,6 +135,27 @@
<!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<TextView
android:id="@+id/label1"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKitoffline"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKitoffline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout

View File

@@ -12,6 +12,10 @@
android:id="@+id/nav_profile"
android:icon="@drawable/control_panel"
android:title="@string/profile" />
<item
android:id="@+id/nav_activity"
android:icon="@drawable/shows_activity_24"
android:title="@string/action_activity" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/baseline_settings_24"

View File

@@ -32,6 +32,11 @@
android:name="com.example.hpostesting.presentation.dashboard.SlideshowFragment"
android:label="@string/action_settings"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_activity"
android:name="com.example.hpostesting.presentation.dashboard.ActivitiesFragment"
android:label="@string/action_activity"
tools:layout="@layout/fragment_activities" />
<activity
android:id="@+id/mainActivity"
android:name="com.example.hpostesting.presentation.MainActivity"

View File

@@ -271,4 +271,5 @@
<string name="deviceinfo">डिवाइस जानकारी</string>
<string name="downloadcsv">सीएसवी डाउनलोड करें</string>
<string name="action_activity">Activities</string>
</resources>

View File

@@ -270,6 +270,7 @@
<string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string>
<string name="ok">ಸರಿ</string>
<string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="action_activity">Activities</string>
<!-- Add translations for other strings -->
</resources>

View File

@@ -273,4 +273,5 @@
<string name="select_language">Select your preferred language</string>
<string name="app_language">App Language</string>
<string name="ok">OK</string>
<string name="action_activity">Activities</string>
</resources>

View File

@@ -3,18 +3,15 @@ package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.presentation.autodac.AutoDacViewModel
import io.mockk.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.setMain

View File

@@ -1,7 +1,7 @@
package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.CsvWriter
import com.example.hpostesting.util.CsvWriter
import org.junit.Assert
import org.junit.Before
import org.junit.Test

View File

@@ -1,26 +1,5 @@
package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import androidx.fragment.app.testing.FragmentScenario
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.lifecycle.MutableLiveData
import androidx.test.core.app.ApplicationProvider
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceBinding
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
class DeviceFragmentTest {
//
// @Mock

View File

@@ -2,7 +2,7 @@ package com.example.hpostesting
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.repository.Repository

View File

@@ -3,6 +3,7 @@ package com.example.hpostesting
import android.content.SharedPreferences
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNull
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers
@@ -23,6 +24,23 @@ class HemoCubeFragmentTest {
hemoCubeFragment = HemoCubeFragment()
}
@Test
fun `extractV2HardwareId to get device id`() {
// Arrange
Mockito.`when`(
mockSharedPreferences.getString(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString()
)
).thenReturn("dummy_value")
// Act
val deviceId = hemoCubeFragment.extractV2HardwareId("SNS HPP1-9000 SNE")
// Assert
assertEquals("HPP1-9000", deviceId)
}
@Test
fun `updateDeviceId in shared pref`() {
// Arrange
@@ -43,4 +61,472 @@ class HemoCubeFragmentTest {
assertEquals("HPP1-0001", deviceId)
}
@Test
fun `allReadingsComplete check`() {
// Arrange
val repeatReadingCount = 1
val readingsPerSample = 1
// Act
val result = hemoCubeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample)
// Assert
assertEquals(true, result)
assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false)
}
@Test
fun `extractV1HardwareId should return hardware ID when input contains SN`() {
// Arrange
val input = "Some text SN ABC123 some more text"
// Act
val result = hemoCubeFragment.extractV1HardwareId(input)
// Assert
assertEquals("ABC123", result)
}
@Test
fun `extractV1HardwareId should return null when input does not contain SN`() {
// Arrange
val input = "Some text without SN"
// Act
val result = hemoCubeFragment.extractV1HardwareId(input)
// Assert
assertNull(result)
}
@Test
fun `extractV1HardwareId should return null when input is empty`() {
// Arrange
val input = ""
// Act
val result = hemoCubeFragment.extractV1HardwareId(input)
// Assert
assertNull(result)
}
@Test
fun `extractV1HardwareId should return null when input is null`() {
// Arrange
val input: String? = null
// Act
val result = input?.let { hemoCubeFragment.extractV1HardwareId(it) }
// Assert
assertNull(result)
}
@Test
fun `extractV1HardwareId should return hardware ID when input contains SN in a specific format`() {
// Arrange
val input = """
SN HCV-000-3001
#BS
#BC
#SS
#SC
RESULT
LB1 20636.32
LB2 15855.67
LB3 21801.36
LB4 18362.33
LS1 17287
LS2 14855.67
LS3 15282.31
LS4 9737.98
REND
""".trimIndent()
// Act
val result = hemoCubeFragment.extractV1HardwareId(input)
// Assert
assertEquals("HCV-000-3001", result)
}
@Test
fun `extractV2HardwareId should return the correct hardware ID when it exists in the input`() {
// Arrange
val input = "SNS ABC123 SNE"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("ABC123", result)
}
@Test
fun `extractV2HardwareId should return null when no hardware ID is found in the input`() {
// Arrange
val input = "No hardware ID in this input"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertNull(result)
}
@Test
fun `extractV2HardwareId should handle whitespace around the hardware ID`() {
// Arrange
val input = "SNS XYZ789 SNE"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("XYZ789", result)
}
@Test
fun `extractV2HardwareId should handle provided input string with HCV-000-3013`() {
// Arrange
val input = "SNS HCV-000-3013 SNE\n" +
"#SS1\n" +
"#SC1\n" +
"RESULT \n" +
"LB1 23411.00\n" +
"LB2 21417.00\n" +
"LB3 23869.00\n" +
"LB4 24967.00\n" +
"LS1 3401.00\n" +
"LS2 1107.00\n" +
"LS3 14410.00\n" +
"LS4 15047.00\n" +
"REND\n"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("HCV-000-3013", result)
}
@Test
fun `extractV2HardwareId should handle provided input string with HPP1-4001`() {
// Arrange
val input = "SNS HPP1-4001 SNE#SS1\n" +
"#SC1\n" +
"RESULT\n" +
"LB1 23777\n" +
"LB2 24130\n" +
"LB3 23442\n" +
"LB4 23945\n" +
"LS1 2521\n" +
"LS2 973\n" +
"LS3 10252\n" +
"LS4 11017\n" +
"REND\n"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("HPP1-4001", result)
}
@Test
fun `extractV2HardwareId should handle provided input string with HPP1-000-4001`() {
// Arrange
val input = "SNS HPP1-000-4001 SNE#SS1\n" +
"#SC1\n" +
"RESULT\n" +
"LB1 23777\n" +
"LB2 24130\n" +
"LB3 23442\n" +
"LB4 23945\n" +
"LS1 2521\n" +
"LS2 973\n" +
"LS3 10252\n" +
"LS4 11017\n" +
"REND\n"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("HPP1-000-4001", result)
}
@Test
fun `extractV2HardwareId should handle provided input string with HPP-000-4001`() {
// Arrange
val input = "SNS HPP-000-4001 SNE#SS1\n" +
"#SC1\n" +
"RESULT\n" +
"LB1 23777\n" +
"LB2 24130\n" +
"LB3 23442\n" +
"LB4 23945\n" +
"LS1 2521\n" +
"LS2 973\n" +
"LS3 10252\n" +
"LS4 11017\n" +
"REND\n"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("HPP-000-4001", result)
}
@Test
fun `extractV2HardwareId should handle provided input string with HPP-000-5001`() {
// Arrange
val input = "SNS HPP-000-5001 SNE#SS1\n" +
"#SC1\n" +
"RESULT\n" +
"LB1 23777\n" +
"LB2 24130\n" +
"LB3 23442\n" +
"LB4 23945\n" +
"LS1 2521\n" +
"LS2 973\n" +
"LS3 10252\n" +
"LS4 11017\n" +
"REND\n"
// Act
val result = hemoCubeFragment.extractV2HardwareId(input)
// Assert
assertEquals("HPP-000-5001", result)
}
@Test
fun testDeviceRatioClassificationNormalWithStartRange() {
val ratio = 0.16
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Normal", result)
}
@Test
fun testDeviceRatioClassificationNormal() {
val ratio = 0.22
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Normal", result)
}
@Test
fun testDeviceRatioClassificationNegativeBorderline() {
val ratio = 0.235
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Negative Borderline", result)
}
@Test
fun testDeviceRatioClassificationSickleCellTraitLowerBound() {
val ratio = 0.251
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationSickleCellTraitUpperBound() {
val ratio = 0.309
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationPositiveForSickleCell() {
val ratio = 0.359
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDiseaseLowerBound() {
val ratio = 0.361
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Disease", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDisease() {
val ratio = 0.45
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Disease", result)
}
@Test
fun testDeviceRatioClassificationInvalid() {
val ratio: Double? = null
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Invalid", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5)
assertEquals("Borderline. Normal", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait2() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellDisease() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.33
)
assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun findResultWithAdditionalMethods_NormalDeviceRatio_ReturnsNormalBelowSlopeRatioThreshold() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 30.0)
assertEquals("Normal", result)
}
@Test
fun findResultWithAdditionalMethods_NBL_ReturnsNBL() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Negative Borderline, Repeat Test",
70.0
)
assertEquals("Negative Borderline, Repeat Test", result)
}
@Test
fun findResultWithAdditionalMethods_SCT_ReturnsSCT() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_PBL_ReturnsPBL() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_SCD_ReturnsSCD() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0)
assertEquals("Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToNormal() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.2
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Normal", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToSCT() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.14
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCell() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.18
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCT() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.195
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCD() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.189
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Disease", result)
}
}

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting
import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.LogFileManager

View File

@@ -1,22 +1,5 @@
package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.math.RoundingMode
import java.text.DecimalFormat
class TestRightViewModelTest {
// private val viewModel = TestRightViewModel()
// private val data = InputData()

View File

@@ -12,15 +12,19 @@ import org.mockito.Mockito
import org.mockito.MockitoAnnotations
class TrueHemeFragmentTest {
@Mock
lateinit var mockContext: Context
@Mock
private lateinit var mockSharedPreferences: SharedPreferences
private lateinit var trueHemeFragment: TrueHemeFragment
private lateinit var fragment: TrueHemeFragment
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
trueHemeFragment = TrueHemeFragment()
fragment = TrueHemeFragment()
}
@Test
@@ -34,7 +38,7 @@ class TrueHemeFragmentTest {
).thenReturn("dummy_value")
// Act
val deviceId = trueHemeFragment.extractV2HardwareId("SNS HPP1-9000 SNE")
val deviceId = fragment.extractV2HardwareId("SNS HPP1-9000 SNE")
// Assert
TestCase.assertEquals("HPP1-9000", deviceId)
@@ -67,11 +71,11 @@ class TrueHemeFragmentTest {
val readingsPerSample = 1
// Act
val result = trueHemeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample)
val result = fragment.allReadingsComplete(repeatReadingCount, readingsPerSample)
// Assert
TestCase.assertEquals(true, result)
TestCase.assertEquals(trueHemeFragment.allReadingsComplete(0, 1), false)
TestCase.assertEquals(fragment.allReadingsComplete(0, 1), false)
}
@Test
@@ -80,7 +84,7 @@ class TrueHemeFragmentTest {
val input = "Some text SN ABC123 some more text"
// Act
val result = trueHemeFragment.extractV1HardwareId(input)
val result = fragment.extractV1HardwareId(input)
// Assert
TestCase.assertEquals("ABC123", result)
@@ -92,7 +96,7 @@ class TrueHemeFragmentTest {
val input = "Some text without SN"
// Act
val result = trueHemeFragment.extractV1HardwareId(input)
val result = fragment.extractV1HardwareId(input)
// Assert
TestCase.assertNull(result)
@@ -104,7 +108,7 @@ class TrueHemeFragmentTest {
val input = ""
// Act
val result = trueHemeFragment.extractV1HardwareId(input)
val result = fragment.extractV1HardwareId(input)
// Assert
TestCase.assertNull(result)
@@ -116,7 +120,7 @@ class TrueHemeFragmentTest {
val input: String? = null
// Act
val result = input?.let { trueHemeFragment.extractV1HardwareId(it) }
val result = input?.let { fragment.extractV1HardwareId(it) }
// Assert
TestCase.assertNull(result)
@@ -144,7 +148,7 @@ class TrueHemeFragmentTest {
""".trimIndent()
// Act
val result = trueHemeFragment.extractV1HardwareId(input)
val result = fragment.extractV1HardwareId(input)
// Assert
TestCase.assertEquals("HCV-000-3001", result)
@@ -156,7 +160,7 @@ class TrueHemeFragmentTest {
val input = "SNS ABC123 SNE"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("ABC123", result)
@@ -168,7 +172,7 @@ class TrueHemeFragmentTest {
val input = "No hardware ID in this input"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertNull(result)
@@ -180,7 +184,7 @@ class TrueHemeFragmentTest {
val input = "SNS XYZ789 SNE"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("XYZ789", result)
@@ -204,7 +208,7 @@ class TrueHemeFragmentTest {
"REND\n"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("HCV-000-3013", result)
@@ -227,7 +231,7 @@ class TrueHemeFragmentTest {
"REND\n"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("HPP1-4001", result)
@@ -250,7 +254,7 @@ class TrueHemeFragmentTest {
"REND\n"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("HPP1-000-4001", result)
@@ -273,7 +277,7 @@ class TrueHemeFragmentTest {
"REND\n"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("HPP-000-4001", result)
@@ -296,236 +300,51 @@ class TrueHemeFragmentTest {
"REND\n"
// Act
val result = trueHemeFragment.extractV2HardwareId(input)
val result = fragment.extractV2HardwareId(input)
// Assert
TestCase.assertEquals("HPP-000-5001", result)
}
@Test
fun testDeviceRatioClassificationNormalWithStartRange() {
val ratio = 0.16
val result = trueHemeFragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Normal", result)
}
@Test
fun testDeviceRatioClassificationNormal() {
val ratio = 0.22
val result = trueHemeFragment.deviceRatioClassification(ratio)
val ratio = 0.25
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Normal", result)
}
@Test
fun testDeviceRatioClassificationNegativeBorderline() {
val ratio = 0.235
val result = trueHemeFragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Negative Borderline", result)
val ratio = 0.31
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Negative Borderline, Repeat Test", result)
}
@Test
fun testDeviceRatioClassificationSickleCellTraitLowerBound() {
val ratio = 0.251
val result = trueHemeFragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationSickleCellTraitUpperBound() {
val ratio = 0.309
val result = trueHemeFragment.deviceRatioClassification(ratio)
fun testDeviceRatioClassificationSickleCellTrait() {
val ratio = 0.34
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationPositiveForSickleCell() {
val ratio = 0.359
val result = trueHemeFragment.deviceRatioClassification(ratio)
val ratio = 0.37
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDiseaseLowerBound() {
val ratio = 0.361
val result = trueHemeFragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Sickle Cell Disease", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDisease() {
val ratio = 0.45
val result = trueHemeFragment.deviceRatioClassification(ratio)
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Sickle Cell Disease", result)
}
@Test
fun testDeviceRatioClassificationInvalid() {
val ratio: Double? = null
val result = trueHemeFragment.deviceRatioClassification(ratio)
val result = fragment.deviceRatioClassification(ratio)
TestCase.assertEquals("Invalid", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() {
val result =
trueHemeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5)
TestCase.assertEquals("Borderline. Normal", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() {
val result =
trueHemeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2)
TestCase.assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait2() {
val result = trueHemeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
TestCase.assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellDisease() {
val result = trueHemeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.33
)
TestCase.assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun findResultWithAdditionalMethods_NormalDeviceRatio_ReturnsNormalBelowSlopeRatioThreshold() {
val result = trueHemeFragment.findResultWithAdditionalMethods(0.5, "Normal", 30.0)
TestCase.assertEquals("Normal", result)
}
@Test
fun findResultWithAdditionalMethods_NBL_ReturnsNBL() {
val result = trueHemeFragment.findResultWithAdditionalMethods(
0.5,
"Negative Borderline, Repeat Test",
70.0
)
TestCase.assertEquals("Negative Borderline, Repeat Test", result)
}
@Test
fun findResultWithAdditionalMethods_SCT_ReturnsSCT() {
val result =
trueHemeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0)
TestCase.assertEquals("Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_PBL_ReturnsPBL() {
val result = trueHemeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
TestCase.assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_SCD_ReturnsSCD() {
val result =
trueHemeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0)
TestCase.assertEquals("Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToNormal() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.2
// Act
val result = trueHemeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
TestCase.assertEquals("Borderline. Normal", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToSCT() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.14
// Act
val result = trueHemeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
TestCase.assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCell() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.18
// Act
val result = trueHemeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
TestCase.assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCT() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.195
// Act
val result = trueHemeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
TestCase.assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCD() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.189
// Act
val result = trueHemeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
TestCase.assertEquals("Borderline. Sickle Cell Disease", result)
}
}

View File

@@ -3,9 +3,9 @@ buildscript {
kotlin_version = '1.8.21'
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.0'
classpath 'com.google.gms:google-services:4.4.0'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1'
classpath 'com.android.tools.build:gradle:8.2.2'
classpath 'com.google.gms:google-services:4.4.1'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.1.0'
}
repositories {
mavenCentral()

View File

@@ -1,4 +1,4 @@
#Mon Jun 12 17:07:47 IST 2023
#Mon Mar 04 17:08:24 IST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip