Compare commits

...

33 Commits

Author SHA1 Message Date
Pritimay Sarkar
039e17a3b8 resolve compile errors since merge 2024-01-03 12:38:13 +05:30
Pritimay Sarkar
f54af3c877 Merge branch 'led-gains-data' into preprod 2024-01-03 12:08:29 +05:30
Pritimay Sarkar
0149ec7111 release 2.1.68 2024-01-03 11:54:21 +05:30
Pritimay Sarkar
c02bd1ba2e release 2.1.65 for pq 2024-01-02 11:38:38 +05:30
Pritimay Sarkar
f6b1b83f24 add gains commands and save gains data 2024-01-02 10:56:38 +05:30
Pritimay Sarkar
7a4b68690d add new slope class thresholds 2023-12-23 18:19:13 +05:30
Pritimay Sarkar
9183c97aef add slope based class 2023-12-21 16:14:29 +05:30
Pritimay Sarkar
72f1231d93 Merge branch 'Feature_New_firmware_changes_for_kit_check_with_4_LED_device' into 'preprod'
Kit check online and offline

See merge request sminnovations/hpos!18
2023-12-20 17:06:41 +00:00
Pritimay Sarkar
dcf340a3a0 Merge branch 'preprod' into 'Feature_New_firmware_changes_for_kit_check_with_4_LED_device'
# Conflicts:
#   app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt
#   app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt
#   app/src/main/java/com/example/hpostesting/presentation/buffercheck/HemoCubeBufferCheckFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt
2023-12-20 17:06:21 +00:00
Mariya
c573390082 ADDED CODE FOR OVF 2023-12-20 17:15:41 +05:30
Pritimay Sarkar
48b2fefd02 Merge branch 'fix-msg-fragmentation' into 'preprod'
Fix msg fragmentation

See merge request sminnovations/hpos!17
2023-12-20 11:13:55 +00:00
Mariya
59aefacec1 string translation for "SCAN QR CODE OF THE KIT" of kannada is Corrected 2023-12-20 11:52:06 +05:30
Pritimay Sarkar
d1b5ca32bf fix msg fragmentation in app and add log dsiplay for admin 2023-12-18 12:48:07 +05:30
Pritimay Sarkar
3e690345c2 handle-msg-fragmentation 2023-12-15 14:37:41 +05:30
Pritimay Sarkar
4f7aa74314 Merge branch 'v2-hardware-config' into preprod 2023-12-15 10:32:56 +05:30
Pritimay Sarkar
590abb5c73 Merge branch 'preprod' 2023-12-15 10:29:48 +05:30
Pritimay Sarkar
7fe8202968 add config error msg and v2 usb config 2023-12-15 10:22:50 +05:30
Kaif
11d4c99e02 Changes for new Arduieno Device 2023-12-14 16:56:39 +05:30
Pritimay Sarkar
2e700601fe release 2.1.52 for qa 2023-12-14 14:53:53 +05:30
Mariya
41798aa37b Digital Card button removed 2023-12-14 13:07:15 +05:30
Mariya
e7600dafec gradle version changed 2023-12-14 12:43:10 +05:30
Mariya
d6b3df25f8 gradle version changed 2023-12-13 20:53:34 +05:30
Mariya
0d7e8b0cd0 Merge remote-tracking branch 'origin/preprod' into preprod 2023-12-13 18:57:03 +05:30
Mariya
3c8570c46b gradle version changed 2023-12-13 18:56:40 +05:30
Pritimay Sarkar
96f9d4d6da coeffs for dev4 2023-12-13 18:55:41 +05:30
Mariya
e7505077ce Merge remote-tracking branch 'origin/preprod' into preprod
# Conflicts:
#	app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
2023-12-12 12:21:52 +05:30
Kaif
41e30cf178 Incremented the version number for giving testing release 2023-12-08 13:59:07 +05:30
Pritimay Sarkar
a34c095fde Merge remote-tracking branch 'origin/Feature_Develop_the_feature_to_shift_between_multiple_languages_in_testing_app' into preprod 2023-12-08 13:55:07 +05:30
Mariya
a3a5c0d6fb pending strings added 2023-12-04 15:49:39 +05:30
Kaif
fb5e6f3b49 Fixed string error 2023-12-01 16:22:13 +05:30
Kaif
8a22b44496 Added app version 2023-12-01 16:10:15 +05:30
Kaif
10d822c5d6 Kannada and Hindi language support added 2023-12-01 15:55:49 +05:30
Kaif
7233305ca3 Kit check online and offline 2023-11-29 22:37:20 +05:30
30 changed files with 1404 additions and 460 deletions

3
.idea/gradle.xml generated
View File

@@ -4,8 +4,6 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="jbr-17" />
<option name="modules"> <option name="modules">
@@ -14,6 +12,7 @@
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
</set> </set>
</option> </option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

View File

@@ -14,13 +14,13 @@ android {
compileSdk 34 compileSdk 34
namespace 'in.sminnovations.hpostesting' namespace 'in.sminnovations.hpostesting'
// prod - production, preprod - preproduction, quality - qc, // prod - production, preprod - preproduction, quality - qc
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting" applicationId "in.sminnovations.hpostesting.quality"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 44 versionCode 68
versionName "2.1.44" versionName "2.1.68"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -133,4 +133,6 @@ dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0" implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "androidx.preference:preference-ktx:1.2.1"
} }

View File

@@ -29,6 +29,8 @@ object Constants {
const val DEVICE_VENDOR_ID = 1027 const val DEVICE_VENDOR_ID = 1027
const val HOMO_CUBE_ID = 29987 const val HOMO_CUBE_ID = 29987
const val VENDOR_ID = 6790 const val VENDOR_ID = 6790
const val HEMO_CUBE_V2_PRODUCT_ID = 24577
const val HEMO_CUBE_V2_VENDOR_ID = 1027
const val ERROR_NORMAL = 400 const val ERROR_NORMAL = 400
const val ERROR_CRITICAL = 401 const val ERROR_CRITICAL = 401
@@ -38,6 +40,7 @@ object Constants {
const val USER_ID = "usernameId" const val USER_ID = "usernameId"
val STATICID = listOf( val STATICID = listOf(
"ADMIN",
"VIZ-1000-0004", "VIZ-1000-0004",
"VIZ-1000-0005", "VIZ-1000-0005",
"VIZ-1000-0006", "VIZ-1000-0006",
@@ -63,6 +66,24 @@ object Constants {
"HC-V1-020", "HC-V1-020",
"HCV-000-3001", "HCV-000-3001",
"HCV-000-3002", "HCV-000-3002",
"HCV-000-3003",
"HCV-000-3004",
"HCV-000-3005",
"HCV-000-3006",
"HCV-000-3007",
"HCV-000-3008",
"HCV-000-3009",
"HCV-000-3010",
"HCV-000-3011",
"HCV-000-3012",
"HCV-000-3013",
"HCV-000-3014",
"HCV-000-3015",
"HCV-000-3016",
"HCV-000-3017",
"HCV-000-3018",
"HCV-000-3019",
"HCV-000-3020"
) )
const val password = "SMI@12345" const val password = "SMI@12345"
@@ -78,6 +99,35 @@ object Constants {
const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_LOWER_BOUND = 21000
const val BUFFER_LED_UPPER_BOUND = 24500 const val BUFFER_LED_UPPER_BOUND = 24500
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_FIRST_GAIN_STARTED = 12.0
const val TEST_STATUS_CODE_FIRST_GAIN_COMPLETED = 13.0
const val TEST_STATUS_CODE_FIRST_GAIN_PRINT_STARTED = 14.0
const val TEST_STATUS_CODE_FIRST_GAIN_PRINT_COMPLETED = 15.0
const val TEST_STATUS_CODE_SECOND_GAIN_STARTED = 16.0
const val TEST_STATUS_CODE_SECOND_GAIN_COMPLETED = 17.0
const val TEST_STATUS_CODE_SECOND_GAIN_PRINT_STARTED = 18.0
const val TEST_STATUS_CODE_SECOND_GAIN_PRINT_COMPLETED = 19.0
const val TEST_STATUS_CODE_THIRD_GAIN_STARTED = 20.0
const val TEST_STATUS_CODE_THIRD_GAIN_COMPLETED = 21.0
const val TEST_STATUS_CODE_THIRD_GAIN_PRINT_STARTED = 22.0
const val TEST_STATUS_CODE_THIRD_GAIN_PRINT_COMPLETED = 23.0
const val TEST_STATUS_CODE_FORTH_GAIN_STARTED = 24.0
const val TEST_STATUS_CODE_FORTH_GAIN_COMPLETED = 25.0
const val TEST_STATUS_CODE_FORTH_GAIN_PRINT_STARTED = 26.0
const val TEST_STATUS_CODE_FORTH_GAIN_PRINT_COMPLETED = 27.0
const val TEST_STATUS_CODE_TEST_COMPLETED = 30.0
val DEVICE_CONFIGURATION: Map<String, List<List<Double>>> = mapOf<String, List<List<Double>>>( val DEVICE_CONFIGURATION: Map<String, List<List<Double>>> = mapOf<String, List<List<Double>>>(
"HCV-000-3001" to listOf( "HCV-000-3001" to listOf(
listOf(1.313, -0.89), // LED1, 435nm listOf(1.313, -0.89), // LED1, 435nm
@@ -91,10 +141,119 @@ object Constants {
listOf(0.1964, 0.011565), // LED3, 555nm listOf(0.1964, 0.011565), // LED3, 555nm
listOf(1.0, 0.0) // LED4 listOf(1.0, 0.0) // LED4
), ),
"HCV-000-3003" to listOf(
listOf(0.723142, -0.09135), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.1964, 0.011565), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3004" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3005" to listOf(
listOf(1.3801, -0.372), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.4565, -0.0371), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3006" to listOf(
listOf(1.3801, -0.372), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.4565, -0.0371), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3007" to listOf(
listOf(1.8445, -0.8213), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.4613, -0.0831), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3008" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3009" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3010" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3011" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3012" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3013" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3014" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3015" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3016" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3017" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3018" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3019" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3020" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
) )
const val INCUBATION_TIME_MIN = 0 const val INCUBATION_TIME_MIN = 0
const val INCUBATION_TIME_MAX = 1400 const val INCUBATION_TIME_MAX = 1400
const val BATTERY_LEVEL_MIN = 0
val BUFFER_INTENSITY_THRESHOLDS: Map<String, List<List<Int>>> = mapOf<String, List<List<Int>>>( val BUFFER_INTENSITY_THRESHOLDS: Map<String, List<List<Int>>> = mapOf<String, List<List<Int>>>(
"HCV-000-3001" to listOf( "HCV-000-3001" to listOf(
@@ -108,6 +267,114 @@ object Constants {
listOf(24500, 26250), listOf(24500, 26250),
listOf(24500, 26250), listOf(24500, 26250),
listOf(24500, 26250), listOf(24500, 26250),
) ),
"HCV-000-3003" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3004" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3005" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3006" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3007" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3008" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3009" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3010" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3011" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3012" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3013" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3014" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3015" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3016" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3017" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3018" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3019" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3020" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
) )
} }

View File

@@ -4,6 +4,10 @@ enum class HemoCubeCommands(val command: String) {
startBuffer("B\r"), startBuffer("B\r"),
runDiagnostics("D\r"), runDiagnostics("D\r"),
startSample("S\r"), startSample("S\r"),
getSample("P\r"), PRINT_COMMAND("P\r"),
getDeviceId("I\r"), getDeviceId("I\r"),
FIRST_GAIN_COMMAND("T\r"),
SECOND_GAIN_COMMAND("U\r"),
THIRD_GAIN_COMMAND("V\r"),
FORTH_GAIN_COMMAND("W\r"),
} }

View File

@@ -0,0 +1,30 @@
package com.example.hpostesting.data.constant
import android.content.Context
import android.content.SharedPreferences
import java.util.Locale
object LanguageManager {
private const val LANGUAGE_PREF_KEY = "language_pref"
fun setLocale(context: Context, languageCode: String) {
val locale = Locale(languageCode)
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.setLocale(locale)
context.createConfigurationContext(configuration)
}
fun persistLanguagePreference(context: Context, languageCode: String) {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
prefs.edit().putString(LANGUAGE_PREF_KEY, languageCode).apply()
}
fun getSavedLanguage(context: Context): String {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
return prefs.getString(LANGUAGE_PREF_KEY, "en") ?: "en"
}
}

View File

@@ -0,0 +1,26 @@
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.BufferCheckData
@Dao
interface HemoCubeBufferDao {
@Query("SELECT * from hemo_cube_buffer_test_table")
fun getAll(): LiveData<List<BufferCheckData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(bufferCheckData: BufferCheckData)
@Query("SELECT * FROM hemo_cube_buffer_test_table WHERE _id = :id")
suspend fun getUserByID(id: String): BufferCheckData
@Query("DELETE FROM hemo_cube_buffer_test_table WHERE _id = :id")
suspend fun deleteById(id: String)
@Query("UPDATE hemo_cube_buffer_test_table SET localFlag = :newValue WHERE _id = :id")
suspend fun updateFieldById(id: String, newValue: Boolean)
}

View File

@@ -1,19 +1,17 @@
package com.example.hpostesting.data.dao package com.example.hpostesting.data.dao
import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters 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.DeviceData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.google.android.datatransport.runtime.dagger.Provides import com.example.hpostesting.data.model.patient.UserData
import javax.inject.Singleton
@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 11, exportSchema = false) @Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 17, exportSchema = false)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() { abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun hemoCubeDao(): HemoCubeDao abstract fun hemoCubeDao(): HemoCubeDao
abstract fun hemoCubeBufferDao(): HemoCubeBufferDao
} }

View File

@@ -1,21 +1,47 @@
package com.example.hpostesting.data.model.patient package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_buffer_test_table")
data class BufferCheckData( data class BufferCheckData(
@PrimaryKey
var _id: String = "",
var kitno: String = "", var kitno: String = "",
var deviceId: String? = "", var deviceId: String? = "",
var appVersion:String? = "", var appVersion:String? = "",
var deviceSerialNumber: String = "", var deviceSerialNumber: String = "",
var deviceType: String = "HEMOCUBE", var deviceType: String = "HEMOCUBE",
var localFlag: Boolean = false,
var resultData: String = "", var resultData: String = "",
var led1Buffer: Double? = null, var led1Buffer: Double? = null,
var led2Buffer: Double? = null, var led2Buffer: Double? = null,
var led3Buffer: Double? = null,
var led4Buffer: Double? = null,
var led1Sample: Double? = null, var led1Sample: Double? = null,
var led2Sample: Double? = null, var led2Sample: Double? = null,
var led3Sample: Double? = null,
var led4Sample: Double? = null,
var led1Average: Double? = null, var led1Average: Double? = null,
var led2Average: 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 deviceRatio: Double? = null, var deviceRatio: Double? = null,
var calculatedRatio: Double? = null, var calculatedRatio: Double? = null,
var predictedDenovixRatio: Double? = null,
var coefficients: String? = "", var coefficients: String? = "",
var classificationResult: String = "", var classificationResult: String = "",
var testTime: String = "" var testTime: String = "",
var prdClassification: String = "",
var errorMessages: String = "",
var batteryLevel: String = "",
var batteryCapacity: String = "",
var batteryMaxCapacity: String = "",
var batteryTemperature: String = "",
var batteryVoltage: String = "",
var reportUploadTime: String? = "",
) )

View File

@@ -43,12 +43,31 @@ data class HemoCubeTestData(
var abs2: Double? = null, var abs2: Double? = null,
var abs3: Double? = null, var abs3: Double? = null,
var abs4: Double? = null, var abs4: 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 deviceRatio: Double? = null, var deviceRatio: Double? = null,
var calculatedRatio: Double? = null, var calculatedRatio: Double? = null,
var predictedDenovixRatio: Double? = null, var predictedDenovixRatio: Double? = null,
var slopeRatio: Double? = null,
var coefficients: String? = "", var coefficients: String? = "",
var classificationResult: String = "", var classificationResult: String = "",
var prdClassification: String = "", var prdClassification: String = "",
var deviceRatioClass: String = "",
var slopeRatioClass: String = "",
var errorMessages: String = "", var errorMessages: String = "",
var batteryLevel: String = "", var batteryLevel: String = "",
var batteryCapacity: String = "", var batteryCapacity: String = "",

View File

@@ -3,6 +3,7 @@ package com.example.hpostesting.domain.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
@@ -44,6 +45,12 @@ object AppModule {
fun provideMyHemo(myDatabase: MyDatabase): HemoCubeDao { fun provideMyHemo(myDatabase: MyDatabase): HemoCubeDao {
return myDatabase.hemoCubeDao() return myDatabase.hemoCubeDao()
} }
@Provides
@Singleton
fun provideMyHemoCubeBuffer(myDatabase: MyDatabase): HemoCubeBufferDao {
return myDatabase.hemoCubeBufferDao()
}
@Provides @Provides
@Singleton @Singleton

View File

@@ -11,6 +11,7 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity import com.example.hpostesting.presentation.testRight.TestRightActivity
@@ -44,6 +45,12 @@ class KitScanActivity : AppCompatActivity() {
binding.nameEditText.setText(contents) binding.nameEditText.setText(contents)
} }
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.google.android.gms.location.* import com.google.android.gms.location.*
@@ -44,6 +45,12 @@ class MainActivity : AppCompatActivity() {
} }
} }
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
@@ -107,6 +114,15 @@ class MainActivity : AppCompatActivity() {
Constants.DEVICE_TYPE_HOMOCUBE Constants.DEVICE_TYPE_HOMOCUBE
} }
device.productId == Constants.HEMO_CUBE_V2_PRODUCT_ID && device.vendorId == Constants.HEMO_CUBE_V2_VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE)
Constants.DEVICE_TYPE_HOMOCUBE
}
device.productId == Constants.DEVICE_PRODUCT_ID && device.vendorId == Constants.DEVICE_VENDOR_ID -> { device.productId == Constants.DEVICE_PRODUCT_ID && device.vendorId == Constants.DEVICE_VENDOR_ID -> {
Log.d( Log.d(
TAG, TAG,

View File

@@ -2,6 +2,7 @@ package com.example.hpostesting.presentation
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.Manifest import android.Manifest
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
@@ -14,6 +15,7 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.util.MyUtils import com.example.hpostesting.util.MyUtils
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding
@@ -32,6 +34,12 @@ class SplashActivity : AppCompatActivity() {
private var allPermissionsGranted = false private var allPermissionsGranted = false
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater) binding = ActivitySplashBinding.inflate(layoutInflater)

View File

@@ -26,6 +26,7 @@ import android.widget.AutoCompleteTextView
import androidx.core.content.ContextCompat.getSystemService import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
@@ -94,13 +95,13 @@ class UserListAdapter(
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
.setView(dialogView) .setView(dialogView)
.setTitle("Add Blood Group") .setTitle(R.string.blood_group)
val etBloodGroup = dialogView.findViewById<AutoCompleteTextView>(R.id.et_blood_group) val etBloodGroup = dialogView.findViewById<AutoCompleteTextView>(R.id.et_blood_group)
builder.setPositiveButton("OK") { dialog, which -> builder.setPositiveButton(R.string.ok) { dialog, which ->
val bloodGroup = etBloodGroup.text.toString() val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.equals("Select Blood Group") || bloodGroup.isNullOrBlank()) { if (bloodGroup.equals("Select Blood Group") ||bloodGroup.equals("ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ") || bloodGroup.isNullOrBlank()) {
if (view != null) { if (view != null) {
etBloodGroup.error =view.context.getString(R.string.blood_group_error) etBloodGroup.error =view.context.getString(R.string.blood_group_error)
} }
@@ -166,7 +167,7 @@ class UserListAdapter(
// Handle the selected blood group here // Handle the selected blood group here
} }
builder.setNegativeButton("Cancel") { dialog, which -> builder.setNegativeButton(R.string.cancel) { dialog, which ->
dialog.dismiss() dialog.dismiss()
} }
@@ -196,7 +197,7 @@ class UserListAdapter(
// } // }
} }
userCard.setOnClickListener { userCard.setOnClickListener {
if (batLevel < 40) { if (batLevel < Constants.BATTERY_LEVEL_MIN) {
Toast.makeText( Toast.makeText(
view.context, view.context,
context?.getString(R.string.low_battery_warning), context?.getString(R.string.low_battery_warning),
@@ -213,13 +214,13 @@ class UserListAdapter(
).show() ).show()
} else { } else {
if (model.incubationTime != "") { if (model.incubationTime != "") {
if (isBetween15And30Minutes(model.incubationTime) < 15) { if (isBetween15And30Minutes(model.incubationTime) < -15000) {
Toast.makeText( Toast.makeText(
view.context, view.context,
context?.getString(R.string.incubation_not_completed), context?.getString(R.string.incubation_not_completed),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} else if (isBetween15And30Minutes(model.incubationTime) > 30) { } else if (isBetween15And30Minutes(model.incubationTime) > 300000) {
Toast.makeText( Toast.makeText(
view.context, view.context,
context?.getString(R.string.incubation_crossed_30_minutes), context?.getString(R.string.incubation_crossed_30_minutes),

View File

@@ -1,36 +1,30 @@
package com.example.hpostesting.presentation.buffercheck package com.example.hpostesting.presentation.buffercheck
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.log10
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
import java.util.UUID
import kotlin.math.log10
class HemoCubeBufferCheckFragment : Fragment() { class HemoCubeBufferCheckFragment : Fragment() {
@@ -41,9 +35,24 @@ class HemoCubeBufferCheckFragment : Fragment() {
private var resultData: String = "" private var resultData: String = ""
private var kitno: String = "" private var kitno: String = ""
private var isOnline = false private var isOnline = false
private val messages = MutableLiveData<String>()
private var isTestOngoing = false private var isTestOngoing = false
private var startListening = MutableLiveData(false) private var startListening = MutableLiveData(false)
private var led1BufferForDevice = 0.0
private var led2BufferForDevice = 0.0
private var led3BufferForDevice = 0.0
private var led4BufferForDevice = 0.0
private var led1SampleForDevice = 0.0
private var led2SampleForDevice = 0.0
private var led3SampleForDevice = 0.0
private var led4SampleForDevice = 0.0
private var fittedAbs1 = 0.0
private var fittedAbs2 = 0.0
private var fittedAbs3 = 0.0
private var fittedAbs4 = 0.0
private var _predictedDenovixRatio = 0.0
private var validationError = false
private var allErrorMessages = ""
private var deviceHardwareId = ""
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View { ): View {
@@ -64,13 +73,14 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.nameEditText.setText("SMI/SC/") binding.nameEditText.setText("SMI/SC/")
binding.tvTitle.visibility = View.GONE binding.tvTitle.visibility = View.GONE
binding.tvName.visibility = View.GONE binding.tvName.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.GONE
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim() val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) { if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
kitno = serialNumber kitno = serialNumber
listenToHemoCube() listenToHemoCube()
startBufferProcess() getDeviceInfo()
} else { } else {
Toast.makeText(context, R.string.invalid_kit_number, Toast.LENGTH_LONG).show() Toast.makeText(context, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
return@setOnClickListener return@setOnClickListener
@@ -84,17 +94,17 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
} }
binding.btnSamplestart.setOnClickListener {
startSampleProcess()
activity?.runOnUiThread { it.visibility = View.GONE
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
binding.btnSubmit.setOnClickListener {
} }
binding.btnSubmit.isEnabled = false binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false binding.btnSubmit.isClickable = false
binding.btnPlacebuffer.setOnClickListener {
checkAndStartProcess()
it.visibility = View.GONE
}
} }
private fun observeViewModel() { private fun observeViewModel() {
@@ -116,6 +126,10 @@ class HemoCubeBufferCheckFragment : Fragment() {
if (result == "Success") { if (result == "Success") {
showToast(R.string.kit_uploaded) showToast(R.string.kit_uploaded)
} }
if (result == "Error") {
showToast("Error uploading data, Kit result stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
if (result == "Local") { if (result == "Local") {
showToast(R.string.kit_upload_failed) showToast(R.string.kit_upload_failed)
} }
@@ -123,27 +137,24 @@ class HemoCubeBufferCheckFragment : Fragment() {
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
} }
messages.observe(viewLifecycleOwner) { hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it binding.tvSubtitle4.text = it
} }
} }
private fun checkAndStartProcess() {
startBufferProcess()
}
private fun listenToHemoCube() { private fun listenToHemoCube() {
if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
}
val fullReadOutput = StringBuilder()
startListening.postValue(true) startListening.postValue(true)
try { try {
(activity as HemocubeBufferCheckActivity).mService.listenToHemoCube(object : (activity as HemocubeBufferCheckActivity).mService.listenToHemoCube(object :
UsbServiceListener { UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) handleUsbData(stringData)
handleUsbData(stringData, fullReadOutput)
} }
} }
@@ -156,97 +167,212 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
} }
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) { private fun handleUsbData(stringData: String) {
if (stringData.contains("#")) { if (stringData.contains("#")) {
messages.postValue(stringData)
isTestOngoing = true isTestOngoing = true
} }
resultData += fullReadOutput.toString() resultData += stringData
when { when {
stringData.contains("#Buffer Completed") -> showStartSampleDialog() stringData.contains("SN") -> {
stringData.contains("#Sample Completed") -> { val slData = stringData.split(" ")
activity?.runOnUiThread { if (slData.size > 1) {
binding.btnSubmit.isEnabled = true val hardwareId = slData[1].trim()
binding.btnSubmit.isClickable = true deviceHardwareId = hardwareId
with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId)
apply()
}
} }
activity?.runOnUiThread {
binding.tvSubtitle4.visibility = View.VISIBLE
binding.btnPlacebuffer.visibility = View.VISIBLE
}
hemoCubeViewModel.messages.postValue("Start")
}
stringData.contains("#BS") -> {
hemoCubeViewModel.messages.postValue("Buffer Started")
}
stringData.contains("#BC") -> {
activity?.runOnUiThread {
binding.tvSubtitle4.text = "Buffer Completed"
binding.btnSamplestart.visibility = View.VISIBLE
}
}
stringData.contains("#SS") -> {
activity?.runOnUiThread {
binding.tvSubtitle4.text = "Sample Started"
binding.btnSamplestart.visibility = View.GONE
}
}
stringData.contains("#SC") -> {
hemoCubeViewModel.messages.postValue("Sample Completed \nGathering data")
fetchResult() fetchResult()
} }
stringData.contains("RESULT") || resultData.contains("REND") -> { resultData.contains("REND") -> {
var validString: String hemoCubeViewModel.messages.postValue(
val results: List<String> "Data collected \n" + " Processing data"
if (stringData.contains("RESULT")) {
validString = isValidResult(stringData)
if (validString.isEmpty()) {
results = resultData.split("\n")
validString = parseResult(results)
}
} else {
results = resultData.split("\n")
validString = parseResult(results)
}
if (validString.isNotEmpty()) {
handleValidResult(validString)
}
}
}
}
private fun showStartSampleDialog() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Start Sample",
"Do you want to start sample reading?",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
}
private fun handleValidResult(validString: String) {
try {
val result = validString.split(" ")
if (result.size == 8) {
val deviceId = result[2]
val led1BufferForDevice = result[3].toDoubleOrNull()
val led2BufferForDevice = result[4].toDoubleOrNull()
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
val calculateRatio = calculateRatio(deviceRatio)
val classificationResult = findResult(calculateRatio)
messages.postValue(classificationResult)
val bufferData = BufferCheckData(
deviceId= deviceId,
kitno = kitno,
led1Buffer = led1BufferForDevice,
led2Buffer = led2BufferForDevice,
led1Average = led1Average,
led2Average = led2Average,
led1Sample = led1Sample,
led2Sample = led2Sample,
deviceRatio = deviceRatio,
calculatedRatio = calculateRatio,
coefficients = currentDeviceData?.coefficients?.get(0).toString() + ", " + currentDeviceData?.coefficients?.get(1).toString(),
classificationResult = classificationResult,
deviceSerialNumber = sharedPreferences.getString(Constants.USER_ID, "").toString(),
testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
) )
hemoCubeViewModel.uploadHemoCubeResultToDatabaseforbuffercheckN(bufferData) val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex())
var bufferIntensity = resultLines[1].split(' ')[1].trim()
led1BufferForDevice = bufferIntensity.toDoubleOrNull()!!
bufferIntensity = resultLines[2].split(' ')[1].trim()
led2BufferForDevice = bufferIntensity.toDoubleOrNull()!!
bufferIntensity = resultLines[3].split(' ')[1].trim()
led3BufferForDevice = bufferIntensity.toDoubleOrNull()!!
bufferIntensity = resultLines[4].split(' ')[1].trim()
led4BufferForDevice = bufferIntensity.toDoubleOrNull()!!
led1SampleForDevice = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2SampleForDevice = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4SampleForDevice =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
processResult()
} }
}
}
private fun processResult() {
try {
hemoCubeViewModel.messages.postValue("processing result")
val deviceLog = resultData
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
)
val version = pInfo.versionName
val led1Average = log10(led1BufferForDevice.div(led1SampleForDevice))
val led2Average = log10(led2BufferForDevice.div(led2SampleForDevice))
val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice))
val deviceRatio = led3Average / led1Average
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!! || led2BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
1
)
?.get(0)!! || led3BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
2
)
?.get(0)!! || led4BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
3
)?.get(0)!!
) {
validationError = true
allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)"
activity?.runOnUiThread {
binding.errorMessage.text =
"Error: Invalid Test. Improper buffer reading (low)" + "\n"
binding.errorMessage.visibility = View.VISIBLE
}
}
if (led1BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(1)!! || led2BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
1
)
?.get(1)!! || led3BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
2
)
?.get(1)!! || led4BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(
3
)?.get(1)!!
) {
validationError = true
allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n"
activity?.runOnUiThread {
binding.errorMessage.text =
"Error: Invalid Test. Improper buffer reading (high)"
binding.errorMessage.visibility = View.VISIBLE
}
}
var gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(0)
var constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1)
fittedAbs1 = gradient?.times(led1Average)?.plus(constant!!)!!
gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(0)
constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(1)
fittedAbs2 = gradient?.times(led2Average)?.plus(constant!!)!!
gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(0)
constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(1)
fittedAbs3 = gradient?.times(led3Average)?.plus(constant!!)!!
gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(0)
constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(1)
fittedAbs4 = gradient?.times(led4Average)?.plus(constant!!)!!
_predictedDenovixRatio = fittedAbs3.div(fittedAbs1)
if (fittedAbs1 <= fittedAbs2) {
validationError = true
allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n"
activity?.runOnUiThread {
binding.errorMessage.text = "Error: Invalid Test. Problem with de-oxygenation"
binding.errorMessage.visibility = View.VISIBLE
}
}
if (fittedAbs1 < 0 || fittedAbs2 < 0 || fittedAbs3 < 0 || fittedAbs4 < 0) {
validationError = true
activity?.runOnUiThread {
binding.errorMessage.text = "Error: Negative Abs. Redo Kit check Reading"
binding.errorMessage.visibility = View.VISIBLE
}
}
val prdClassification = absorbanceBasedClassification(_predictedDenovixRatio)
hemoCubeViewModel.messages.postValue(prdClassification)
val bufferData = BufferCheckData(
_id = UUID.randomUUID().toString(),
deviceId = deviceHardwareId,
kitno = kitno,
appVersion = version,
led1Buffer = led1BufferForDevice,
led2Buffer = led2BufferForDevice,
led3Buffer = led3BufferForDevice,
led4Buffer = led4BufferForDevice,
led1Sample = led1SampleForDevice,
led2Sample = led2SampleForDevice,
led3Sample = led3SampleForDevice,
led4Sample = led4SampleForDevice,
led1Average = led1Average,
led2Average = led2Average,
led3Average = led3Average,
led4Average = led4Average,
abs1 = fittedAbs1,
abs2 = fittedAbs2,
abs3 = fittedAbs3,
abs4 = fittedAbs4,
deviceRatio = deviceRatio,
resultData = deviceLog,
predictedDenovixRatio = _predictedDenovixRatio,
prdClassification = prdClassification,
errorMessages = allErrorMessages,
coefficients = currentDeviceData?.coefficients?.get(0)
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString(),
deviceSerialNumber = sharedPreferences.getString(Constants.USER_ID, "").toString(),
testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time),
batteryLevel = hemoCubeViewModel.getBatteryLevel().toString(),
batteryCapacity = hemoCubeViewModel.getBatteryCapacity(requireContext()).toString(),
batteryMaxCapacity = hemoCubeViewModel.getBatteryMaxCapacity(requireContext())
.toString(),
batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString(),
batteryVoltage = hemoCubeViewModel.getBatteryVoltage(requireContext()).toString()
)
hemoCubeViewModel.uploadHemoCubeResultToDatabaseForBufferCheck(isOnline, bufferData)
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText( Toast.makeText(
requireContext(), "Error while processing device data", Toast.LENGTH_SHORT requireContext(), "Error while processing device data", Toast.LENGTH_SHORT
@@ -257,23 +383,44 @@ class HemoCubeBufferCheckFragment : Fragment() {
private fun findResult(calculatedRatio: Double?): String { private fun findResult(calculatedRatio: Double?): String {
try { try {
hemoCubeViewModel.messages.postValue("result classification")
if (calculatedRatio != null) { if (calculatedRatio != null) {
if (calculatedRatio < 0.085) return "Kit Failed" if (calculatedRatio < 0.05) return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume"
if (calculatedRatio in 0.085..0.155) return "Kit Passed" if (calculatedRatio in 0.05..0.155) return "Normal"
if (calculatedRatio in 0.155..0.175) return "Kit Failed" if (calculatedRatio in 0.155..0.175) return "Negative Borderline. Repeat Test"
if (calculatedRatio in 0.175..0.22) return "Kit Failed" if (calculatedRatio in 0.175..0.22) return "Sickle Cell Trait"
if (calculatedRatio in 0.22..0.25) return "Kit Failed" if (calculatedRatio in 0.22..0.25) return "Positive for Sickle Cell. HPLC for Confirmation"
if (calculatedRatio in 0.25..0.35) return "Kit Failed" if (calculatedRatio in 0.25..0.35) return "Sickle Cell Disease"
if (calculatedRatio > 0.35) return "Kit Failed" if (calculatedRatio > 0.35) return "Inconclusive. Repeat with test with lower volume of blood"
} else { } else {
return "NULL" return "INVALID"
} }
} catch (e: Exception) { } catch (e: Exception) {
showToast(R.string.error_classification) showToast(R.string.error_classification)
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
return "ERROR" return "ERROR"
} }
return "NULL" return "INVALID"
}
private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String {
try {
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"
if (predictedDenovixRatio in 0.165..0.235) return "Kit Failed"
if (predictedDenovixRatio in 0.235..0.24) return "Kit Failed"
if (predictedDenovixRatio in 0.24..1.0) return "Kit Failed"
} else {
return "INVALID"
}
} catch (e: Exception) {
showToast("error while performing classification")
Firebase.crashlytics.recordException(e)
return "ERROR"
}
return "INVALID"
} }
private fun showToast(messageResId: Int) { private fun showToast(messageResId: Int) {
@@ -282,6 +429,9 @@ class HemoCubeBufferCheckFragment : Fragment() {
private fun startBufferProcess() { private fun startBufferProcess() {
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer, (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer,
object : UsbServiceListener { object : UsbServiceListener {
@@ -293,6 +443,9 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
private fun startSampleProcess() { private fun startSampleProcess() {
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample, (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample,
object : UsbServiceListener { object : UsbServiceListener {
@@ -303,9 +456,28 @@ class HemoCubeBufferCheckFragment : Fragment() {
}) })
} }
private fun getDeviceInfo() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.getDeviceId,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
hemoCubeViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() { private fun fetchResult() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample, (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {} override fun onUsbRead(data: ByteArray?) {}
@@ -320,21 +492,6 @@ class HemoCubeBufferCheckFragment : Fragment() {
return coefficient1 * ratio + coefficient2 return coefficient1 * ratio + coefficient2
} }
private fun parseResult(frames: List<String>): String {
val lines = mutableListOf<String>()
for (frame in frames.reversed()) {
if (frame.contains("REND") || frame.contains("RESULT")) lines += frame
if (frame.contains("RESULT")) {
break
}
}
val line = lines.reversed().joinToString("").trim()
if (line.contains("RESULT") && line.split(" ").size == 8) {
return line
}
return ""
}
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {
if (s.length != 17) { if (s.length != 17) {
binding.nameEditText.error = getString(R.string.invalid_kit) binding.nameEditText.error = getString(R.string.invalid_kit)
@@ -342,13 +499,4 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
return true return true
} }
private fun isValidResult(line: String): String {
return if (line.contains("RESULT") && line.split(" ").size == 8) {
line
} else {
""
}
}
} }

View File

@@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
@@ -73,6 +74,12 @@ open class HemocubeBufferCheckActivity : AppCompatActivity() {
} }
} }
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater) binding = ActivityHemocubeBinding.inflate(layoutInflater)

View File

@@ -1,5 +1,6 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
@@ -10,6 +11,7 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.constant.LanguageManager
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException import com.google.firebase.appdistribution.FirebaseAppDistributionException
@@ -24,6 +26,12 @@ class DashboardActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -162,10 +162,10 @@ class HomeFragment : Fragment() {
val dateFormat = SimpleDateFormat("yyyy-MM-dd") val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val currentDate = Date() val currentDate = Date()
val formattedDate = dateFormat.format(currentDate) val formattedDate = dateFormat.format(currentDate)
// val query = Firebase.firestore.collection("patientData") val query = Firebase.firestore.collection("patientData")
// .whereGreaterThanOrEqualTo("createdAt", formattedDate) .whereGreaterThanOrEqualTo("createdAt", formattedDate)
// .orderBy("createdAt", Query.Direction.DESCENDING) .orderBy("createdAt", Query.Direction.DESCENDING)
val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false) // val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false)
query.get().addOnSuccessListener { query.get().addOnSuccessListener {
if (it.documents.isEmpty()) { if (it.documents.isEmpty()) {
binding.pendingTest.visibility = View.VISIBLE binding.pendingTest.visibility = View.VISIBLE
@@ -311,6 +311,12 @@ class HomeFragment : Fragment() {
if (userDataList.any { !it.localFlag && it.testStatus == true}) View.VISIBLE else View.GONE if (userDataList.any { !it.localFlag && it.testStatus == true}) View.VISIBLE else View.GONE
binding.uploadData.visibility = uploadDataVisibility binding.uploadData.visibility = uploadDataVisibility
} }
hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) {bufferData ->
val uploadDataVisibility =
if (bufferData.any { !it.localFlag}) View.VISIBLE else View.GONE
binding.uploadData.visibility = uploadDataVisibility
}
} }
private fun showUploadDialog(context: Context) { private fun showUploadDialog(context: Context) {
@@ -355,6 +361,16 @@ class HomeFragment : Fragment() {
} }
dialog.dismiss() dialog.dismiss()
} }
hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList ->
kitDataList.forEach { userData ->
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultKitTestToDb(userData)
}
}
dialog.dismiss()
}
} }
private fun deleteIncompleteRegistrations(userDataList: List<UserData>) { private fun deleteIncompleteRegistrations(userDataList: List<UserData>) {

View File

@@ -1,47 +1,66 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.widget.Toast
import android.view.View import androidx.preference.ListPreference
import android.view.ViewGroup import androidx.preference.Preference
import androidx.fragment.app.Fragment import androidx.preference.PreferenceFragmentCompat
import androidx.lifecycle.ViewModelProvider import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding private var isLanguageChanged = false
class SlideshowFragment : Fragment() { class SlideshowFragment : PreferenceFragmentCompat() {
private var _binding: FragmentSlideshowBinding? = null override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext())
// This property is only valid between onCreateView and val languagePreference = ListPreference(requireContext())
// onDestroyView. languagePreference.key = "language_preference"
private val binding get() = _binding!! languagePreference.title = getString(R.string.app_language)
languagePreference.summary = getString(R.string.select_language)
languagePreference.entries = arrayOf("English", "Kannada", "Hindi")
languagePreference.entryValues = arrayOf("en", "kn", "hi")
languagePreference.setDefaultValue("en")
override fun onCreateView( languagePreference.onPreferenceChangeListener =
inflater: LayoutInflater, Preference.OnPreferenceChangeListener { _, newValue ->
container: ViewGroup?, val languageCode = newValue as String
savedInstanceState: Bundle?, updateLanguage(requireContext(), languageCode)
): View { true
val slideshowViewModel = }
ViewModelProvider(this).get(SlideshowViewModel::class.java)
_binding = FragmentSlideshowBinding.inflate(inflater, container, false) preferenceScreen.addPreference(languagePreference)
val root: View = binding.root setPreferenceScreen(preferenceScreen)
val pInfo = requireActivity().packageManager.getPackageInfo( // App Version Preference
requireActivity().packageName, 0 val appVersionPreference = Preference(requireContext())
) appVersionPreference.title = "App Version"
val version = pInfo.versionName appVersionPreference.summary = getAppVersion(requireContext())
binding.textSlideshow.text = version
// val textView: TextView = binding.textSlideshow preferenceScreen.addPreference(languagePreference)
// slideshowViewModel.text.observe(viewLifecycleOwner) { preferenceScreen.addPreference(appVersionPreference)
// textView.text = it setPreferenceScreen(preferenceScreen)
// }
return root if (isLanguageChanged) {
Toast.makeText(requireContext(), R.string.language_update, Toast.LENGTH_SHORT).show()
}
} }
override fun onDestroyView() { private fun updateLanguage(context: Context, languageCode: String) {
super.onDestroyView() LanguageManager.persistLanguagePreference(context, languageCode)
_binding = null LanguageManager.setLocale(context, languageCode)
requireActivity().recreate() // Recreate activity to apply language changes
isLanguageChanged = true
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
} }
} }

View File

@@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants 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.HemoCubeFragment
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
@@ -77,6 +78,12 @@ class DiagnosticsActivity : AppCompatActivity() {
} }
} }
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDiagnosticsBinding.inflate(layoutInflater) binding = ActivityDiagnosticsBinding.inflate(layoutInflater)

View File

@@ -14,6 +14,7 @@ import android.os.IBinder
import android.view.Menu import android.view.Menu
import androidx.activity.viewModels import androidx.activity.viewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
@@ -21,8 +22,15 @@ import `in`.sminnovations.hpostesting.databinding.ActivityDigitalCardBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
class DigitalCardActivity : AppCompatActivity() { class DigitalCardActivity : AppCompatActivity() {
private lateinit var binding: ActivityDigitalCardBinding private lateinit var binding: ActivityDigitalCardBinding
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDigitalCardBinding.inflate(layoutInflater) binding = ActivityDigitalCardBinding.inflate(layoutInflater)

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
@@ -19,7 +18,7 @@ import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
@@ -27,7 +26,9 @@ import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.ktx.performance import com.google.firebase.perf.ktx.performance
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.abs
import kotlin.math.log10 import kotlin.math.log10
import kotlin.math.round
class HemoCubeFragment : Fragment() { class HemoCubeFragment : Fragment() {
@@ -38,6 +39,7 @@ class HemoCubeFragment : Fragment() {
private var isOnline = false private var isOnline = false
private var currentDeviceData: DeviceData? = null private var currentDeviceData: DeviceData? = null
private var resultData: String = "" private var resultData: String = ""
private var currentResultData: String = ""
private var isUsingExistingBuffer = false private var isUsingExistingBuffer = false
private var isTestOngoing = false private var isTestOngoing = false
private var startListening = MutableLiveData<Boolean>(false) private var startListening = MutableLiveData<Boolean>(false)
@@ -58,6 +60,7 @@ class HemoCubeFragment : Fragment() {
private var validationError = false private var validationError = false
private var deviceHardwareId = "" private var deviceHardwareId = ""
private var allErrorMessages = "" private var allErrorMessages = ""
private var testStatusCode = 0.0
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
@@ -122,6 +125,11 @@ class HemoCubeFragment : Fragment() {
} }
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
activity?.runOnUiThread {
binding.tvDeviceMessages.visibility = View.VISIBLE
}
}
} }
private fun observeViewModel() { private fun observeViewModel() {
@@ -131,13 +139,11 @@ class HemoCubeFragment : Fragment() {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
binding.btnDigitalCard.visibility = View.VISIBLE
binding.btnDigitalCard.setOnClickListener {
val i = Intent( val i = Intent(
requireContext().applicationContext, DigitalCardActivity::class.java requireContext().applicationContext, DashboardActivity::class.java
) )
startActivity(i) startActivity(i)
}
} }
} }
if (result == "Local") { if (result == "Local") {
@@ -174,6 +180,10 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.messages.observe(viewLifecycleOwner) { hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it binding.tvSubtitle4.text = it
} }
hemoCubeViewModel.deviceMessages.observe(viewLifecycleOwner) {
binding.tvDeviceMessages.text = it
}
} }
private fun checkAndStartProcess() { private fun checkAndStartProcess() {
@@ -242,7 +252,6 @@ class HemoCubeFragment : Fragment() {
if (DataHolder.hemoCubeTestData == null) { if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData() DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
} }
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
@@ -254,7 +263,7 @@ class HemoCubeFragment : Fragment() {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput) handleUsbData(stringData)
} }
} }
@@ -287,23 +296,30 @@ class HemoCubeFragment : Fragment() {
}) })
} }
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) { private fun handleUsbData(stringData: String) {
if (stringData.contains("#")) { if (stringData.contains("#")) {
isTestOngoing = true isTestOngoing = true
} }
resultData += stringData resultData += stringData
currentResultData += stringData
hemoCubeViewModel.deviceMessages.postValue(currentResultData)
when { when {
stringData.contains("SN") -> { resultData.contains("SNE") && this.testStatusCode < Constants.TEST_STATUS_CODE_CONFIG_COMPLETED -> {
val slData = stringData.split(" ") val pattern = Regex("HCV-\\d{3}-\\d{4}")
if (slData.size > 1) { val matchResult = pattern.find(resultData)
val hardwareId = slData[1].trim() val hardwareId = matchResult?.value
deviceHardwareId = hardwareId
if (hardwareId.toString().length == 12) {
deviceHardwareId += hardwareId
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId) putString(Constants.DEVICE_ID, deviceHardwareId)
apply() apply()
} }
this.testStatusCode = Constants.TEST_STATUS_CODE_CONFIG_COMPLETED
} else {
hemoCubeViewModel.messages.postValue("Config error")
} }
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE binding.btnPlacebuffer.visibility = View.VISIBLE
@@ -311,35 +327,81 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.messages.postValue(getString(R.string.start)) hemoCubeViewModel.messages.postValue(getString(R.string.start))
} }
stringData.contains("#BS") -> { resultData.contains("#BS") && this.testStatusCode < Constants.TEST_STATUS_CODE_BUFFER_STARTED -> {
hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started)) hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started))
this.testStatusCode = Constants.TEST_STATUS_CODE_BUFFER_STARTED
} }
stringData.contains("#BC") -> { resultData.contains("#BC") && this.testStatusCode < Constants.TEST_STATUS_CODE_BUFFER_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_BUFFER_COMPLETED
activity?.runOnUiThread { activity?.runOnUiThread {
binding.tvSubtitle4.text = getString(R.string.buffer_completed) binding.tvSubtitle4.text = getString(R.string.buffer_completed)
binding.btnSamplestart.visibility = View.VISIBLE binding.btnSamplestart.visibility = View.VISIBLE
} }
} }
stringData.contains("#SS") -> { resultData.contains("#SS1") && this.testStatusCode < Constants.TEST_STATUS_CODE_SAMPLE_STARTED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SAMPLE_STARTED
activity?.runOnUiThread { activity?.runOnUiThread {
binding.tvSubtitle4.text = getString(R.string.sample_started) binding.tvSubtitle4.text = getString(R.string.sample_started)
binding.btnSamplestart.visibility = View.GONE binding.btnSamplestart.visibility = View.GONE
} }
} }
stringData.contains("#SC") -> { resultData.contains("#SC1") && this.testStatusCode < Constants.TEST_STATUS_CODE_SAMPLE_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SAMPLE_COMPLETED
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data)) getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data))
fetchResult() fetchResult()
currentResultData = ""
testingTrace.stop() testingTrace.stop()
} }
resultData.contains("REND") -> { resultData.contains("ovf") -> {
hemoCubeViewModel.messages.postValue(
getString(R.string.power_bank)
)
}
currentResultData.contains("#SS2") && this.testStatusCode < Constants.TEST_STATUS_CODE_FIRST_GAIN_STARTED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FIRST_GAIN_STARTED
hemoCubeViewModel.messages.postValue("1.3X Gain Started")
}
currentResultData.contains("#SC2") && this.testStatusCode < Constants.TEST_STATUS_CODE_FIRST_GAIN_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FIRST_GAIN_COMPLETED
hemoCubeViewModel.messages.postValue("1.3X Gain Completed")
fetchResult()
}
currentResultData.contains("#SS3") && this.testStatusCode < Constants.TEST_STATUS_CODE_SECOND_GAIN_STARTED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SECOND_GAIN_STARTED
hemoCubeViewModel.messages.postValue("2X Gain Started")
}
currentResultData.contains("#SC3") && this.testStatusCode < Constants.TEST_STATUS_CODE_SECOND_GAIN_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SECOND_GAIN_COMPLETED
hemoCubeViewModel.messages.postValue("2X Gain Completed")
fetchResult()
}
currentResultData.contains("#SS5") && this.testStatusCode < Constants.TEST_STATUS_CODE_FORTH_GAIN_STARTED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FORTH_GAIN_STARTED
hemoCubeViewModel.messages.postValue("7.6X Gain Started")
}
currentResultData.contains("#SC5") && this.testStatusCode < Constants.TEST_STATUS_CODE_FORTH_GAIN_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FORTH_GAIN_COMPLETED
hemoCubeViewModel.messages.postValue("7.6X Gain Completed")
fetchResult()
}
resultData.contains("REND") && this.testStatusCode < Constants.TEST_STATUS_CODE_SAMPLE_PRINT_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SAMPLE_PRINT_COMPLETED
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
getString(R.string.data_collected_processing_data) getString(R.string.data_collected_processing_data)
) )
val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex())
var bufferIntensity = resultLines[1].split(' ')[1].trim() var bufferIntensity = resultLines[1].split(' ')[1].trim()
led1BufferForDevice = if (isUsingExistingBuffer) { led1BufferForDevice = if (isUsingExistingBuffer) {
@@ -376,6 +438,60 @@ class HemoCubeFragment : Fragment() {
led4SampleForDevice = led4SampleForDevice =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
processResult() processResult()
sendFirstGainCommand()
currentResultData = ""
}
currentResultData.contains("REND") && this.testStatusCode >= Constants.TEST_STATUS_CODE_FIRST_GAIN_COMPLETED && this.testStatusCode < Constants.TEST_STATUS_CODE_FIRST_GAIN_PRINT_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FIRST_GAIN_PRINT_COMPLETED
hemoCubeViewModel.messages.postValue("1.3X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.hemoCubeTestData?.apply {
led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain1 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
}
sendSecondGainCommand()
currentResultData = ""
}
currentResultData.contains("REND") && this.testStatusCode >= Constants.TEST_STATUS_CODE_FIRST_GAIN_PRINT_COMPLETED && this.testStatusCode < Constants.TEST_STATUS_CODE_SECOND_GAIN_PRINT_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_SECOND_GAIN_PRINT_COMPLETED
hemoCubeViewModel.messages.postValue("2X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.hemoCubeTestData?.apply {
led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain2 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
}
sendForthGainCommand()
currentResultData = ""
}
currentResultData.contains("REND") && this.testStatusCode >= Constants.TEST_STATUS_CODE_SECOND_GAIN_PRINT_COMPLETED && this.testStatusCode < Constants.TEST_STATUS_CODE_FORTH_GAIN_PRINT_COMPLETED -> {
this.testStatusCode = Constants.TEST_STATUS_CODE_FORTH_GAIN_PRINT_COMPLETED
hemoCubeViewModel.messages.postValue("7.6X gain data gathered")
val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex())
DataHolder.hemoCubeTestData?.apply {
led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain4 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
}
} }
} }
} }
@@ -463,8 +579,6 @@ class HemoCubeFragment : Fragment() {
binding.errorMessage.text = binding.errorMessage.text =
getString(R.string.error_improper_buffer_high) getString(R.string.error_improper_buffer_high)
binding.errorMessage.visibility = View.VISIBLE binding.errorMessage.visibility = View.VISIBLE
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
} }
} }
@@ -486,6 +600,10 @@ class HemoCubeFragment : Fragment() {
_predictedDenovixRatio = fittedAbs3.div(fittedAbs1) _predictedDenovixRatio = fittedAbs3.div(fittedAbs1)
val slope = (led1Average - led2Average) / (435 - 415)
val _slopeRatio = abs(led3Average / slope)
val slopeClass = slopeRatioClassification(_slopeRatio)
if (fittedAbs1 <= fittedAbs2) { if (fittedAbs1 <= fittedAbs2) {
validationError = true validationError = true
allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n" allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n"
@@ -503,6 +621,14 @@ class HemoCubeFragment : Fragment() {
} }
} }
if ((led1Average < 0.7 || led2Average < 0.7 || led3Average < 0.7 || led4Average < 0.7) && _slopeRatio > 35.0) {
validationError = true
activity?.runOnUiThread {
binding.errorMessage.text = "Severely Low Hb. Repeat test with 12 ul in 2 ml Buffer"
binding.errorMessage.visibility = View.VISIBLE
}
}
if (fittedAbs3 < 0.1) { if (fittedAbs3 < 0.1) {
validationError = true validationError = true
allErrorMessages += "Error: Low Hb. Repeat test" + "\n" allErrorMessages += "Error: Low Hb. Repeat test" + "\n"
@@ -534,11 +660,14 @@ class HemoCubeFragment : Fragment() {
this.deviceRatio = deviceRatio this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio) this.calculatedRatio = calculateRatio(deviceRatio)
this.predictedDenovixRatio = _predictedDenovixRatio this.predictedDenovixRatio = _predictedDenovixRatio
this.slopeRatio = _slopeRatio
this.coefficients = currentDeviceData?.coefficients?.get(0) this.coefficients = currentDeviceData?.coefficients?.get(0)
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.classificationResult = findResult(calculatedRatio) this.classificationResult = findResult(calculatedRatio)
this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
hemoCubeViewModel.messages.postValue(this.prdClassification) this.deviceRatioClass = deviceRatioClassification(deviceRatio)
this.slopeRatioClass = slopeClass
hemoCubeViewModel.messages.postValue("Slope Ratio: ${round(slopeRatio!!)},\n Slope Class: ${this.slopeRatioClass}\n")
this.errorMessages = allErrorMessages this.errorMessages = allErrorMessages
this.resultData = deviceLog this.resultData = deviceLog
this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString() this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString()
@@ -562,12 +691,12 @@ class HemoCubeFragment : Fragment() {
} }
// if (!validationError) { // if (!validationError) {
activity?.runOnUiThread { // activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE // binding.btnSubmit.visibility = View.VISIBLE
binding.btnSubmit.isEnabled = true // binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true // binding.btnSubmit.isClickable = true
binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) // binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
} // }
// } // }
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText( Toast.makeText(
@@ -608,6 +737,56 @@ class HemoCubeFragment : Fragment() {
return getString(R.string.invalid) return getString(R.string.invalid)
} }
fun deviceRatioClassification(ratio: Double?): String {
try {
hemoCubeViewModel.messages.postValue("result classification")
if (ratio != null) {
if (ratio in 0.0..0.4)
return getString(R.string.normal)
if (ratio in 0.4..0.45)
return getString(R.string.negative_borderline)
if (ratio in 0.45..0.55)
return getString(R.string.sickle_cell_trait)
if (ratio in 0.55..0.575)
return getString(R.string.positive_for_sickle_cell)
if (ratio in 0.09..1.0)
return getString(R.string.sickle_cell_disease)
} else {
return getString(R.string.invalid)
}
} catch (e: Exception) {
showToast(R.string.error_classification)
Firebase.crashlytics.recordException(e)
return getString(R.string.error)
}
return getString(R.string.invalid)
}
fun slopeRatioClassification(ratio: Double?): String {
try {
hemoCubeViewModel.messages.postValue("result classification")
if (ratio != null) {
if (ratio in 0.0..30.0)
return getString(R.string.normal)
if (ratio in 30.0..35.0)
return getString(R.string.negative_borderline)
if (ratio in 35.0..50.0)
return getString(R.string.sickle_cell_trait)
if (ratio in 50.0..60.0)
return getString(R.string.positive_for_sickle_cell)
if (ratio > 60.0)
return getString(R.string.sickle_cell_disease)
} else {
return getString(R.string.invalid)
}
} catch (e: Exception) {
showToast(R.string.error_classification)
Firebase.crashlytics.recordException(e)
return getString(R.string.error)
}
return getString(R.string.invalid)
}
private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String {
try { try {
hemoCubeViewModel.messages.postValue("result classification") hemoCubeViewModel.messages.postValue("result classification")
@@ -668,10 +847,62 @@ class HemoCubeFragment : Fragment() {
}) })
} }
private fun sendFirstGainCommand() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FIRST_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendSecondGainCommand() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.SECOND_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendThirdGainCommand() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.THIRD_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun sendForthGainCommand() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FORTH_GAIN_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() { private fun fetchResult() {
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample, (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {} override fun onUsbRead(data: ByteArray?) {}
@@ -692,4 +923,4 @@ class HemoCubeFragment : Fragment() {
return true return true
return false return false
} }
} }

View File

@@ -1,13 +1,11 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import android.app.Application
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.BatteryManager import android.os.BatteryManager
import android.util.Log import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@@ -15,14 +13,13 @@ import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants 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.HemoCubeDao
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -34,246 +31,324 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class HemoCubeViewModel @Inject constructor( class HemoCubeViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao, private val hemoCubeDao: HemoCubeDao,
private val hemoCubeBufferDao: HemoCubeBufferDao,
private val repository: Repository, private val repository: Repository,
context: Context, context: Context,
) : ViewModel() { ) : ViewModel() {
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>() val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences = private val sharedPreference: SharedPreferences =
context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
// Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) // 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) private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll() val allUserData = hemoCubeDao.getAll()
val deviceData = MutableLiveData<DeviceData?>() val allKitTestData = hemoCubeBufferDao.getAll()
val networkStatusLiveData: LiveData<Boolean> val deviceData = MutableLiveData<DeviceData?>()
get() = _networkStatusLiveData val networkStatusLiveData: LiveData<Boolean>
val fireBaseUpload = MutableLiveData<String>() get() = _networkStatusLiveData
val fireBaseBulkUpload = MutableLiveData<String>() val deviceMessages = MutableLiveData<String?>()
val fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
private val batteryStatus: Intent? = private val batteryStatus: Intent? =
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, 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 uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch {
addResultTestToDbforbuffercheck(bufferCheckData)
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
} }
private fun parseData() { fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) =
testDetails?.deviceRatio = DataHolder.hemocubeResult viewModelScope.launch {
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() if (kitSerial != null) {
testDetails?.location = DataHolder.location testDetails?.kitSerial = kitSerial
testDetails?.testTime = SimpleDateFormat( }
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() testDetails?.testStatus = testStatus
).format(Calendar.getInstance().time)
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.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?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients
testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!!
testDetails?.prdClassification =
DataHolder.hemoCubeTestData?.prdClassification.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()
}
private fun addResultTestToDb() { try {
viewModelScope.launch { if (isOnline) {
try { parseData()
testDetails!!.reportUploadTime = SimpleDateFormat( addResultTestToDb()
} else {
parseData()
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
hemoCubeDao.insertAll(testDetails!!)
when (val response = repository.addTestToDatabase(testDetails)) { fireBaseUpload.postValue("Local")
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
hemoCubeDao.insertAll(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
hemoCubeDao.insertAll(testDetails)
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
} }
} catch (e: Exception) {
Log.e("Testdb", "Upload failed: ${e.message}")
} }
} }
private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch { viewModelScope.launch {
try { addResultTestToDbforbuffercheck(bufferCheckData)
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean,
bufferCheckData: BufferCheckData,
) =
viewModelScope.launch {
if (isOnline) {
try {
when (val response = when (val response =
repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
is Response.Success -> { is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully") Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success") fireBaseUpload.postValue("Success")
bufferCheckData.localFlag = true
hemoCubeBufferDao.insertAll(bufferCheckData)
} }
is Response.Error -> { is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
bufferCheckData.localFlag = true
hemoCubeBufferDao.insertAll(bufferCheckData)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
} }
} else {
hemoCubeBufferDao.insertAll(bufferCheckData)
fireBaseUpload.postValue("Local")
} }
} }
fun bulkAddResultTestToDb(userData: HemoCubeTestData) { private fun parseData() {
viewModelScope.launch { testDetails?.deviceRatio = DataHolder.hemocubeResult
userData.reportUploadTime = SimpleDateFormat( 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.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.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?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients
testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!!
testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.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()
}
private fun addResultTestToDb() {
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
when (val response = repository.addTestToDatabase(testDetails)) {
is Response.Success -> { is Response.Success -> {
fireBaseBulkUpload.postValue("Success") val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
updateLocalFlag(userData._id) with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
hemoCubeDao.insertAll(testDetails)
} }
else -> { is Response.Error -> {
fireBaseBulkUpload.postValue("Error") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
hemoCubeDao.insertAll(testDetails)
} }
} }
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
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")
}
} }
} }
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch { private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) {
viewModelScope.launch {
try {
when (val response =
repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
private fun updateBufferLocalFlag(bufferId: String) =
viewModelScope.launch {
hemoCubeBufferDao.updateFieldById(id = bufferId, true)
}
fun bulkAddResultTestToDb(userData: HemoCubeTestData) {
viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseBulkUpload.postValue("Success")
updateLocalFlag(userData._id)
}
else -> {
fireBaseBulkUpload.postValue("Error")
}
}
}
}
private fun updateLocalFlag(userId: String) =
viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true) hemoCubeDao.updateFieldById(id = userId, true)
} }
fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { fun addUser(userData: HemoCubeTestData) =
viewModelScope.launch {
hemoCubeDao.insertAll(userData) hemoCubeDao.insertAll(userData)
} }
fun deleteById(userId: String) = viewModelScope.launch { fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId) hemoCubeDao.deleteById(id = userId)
}
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) ?: 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 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
) ?: 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
}
}

View File

@@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -72,6 +73,12 @@ open class HemocubeActivity : AppCompatActivity() {
viewModel.isServiceConnected = false viewModel.isServiceConnected = false
} }
} }
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -195,16 +195,36 @@
style="@style/title1_1" style="@style/title1_1"
android:visibility="gone" android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="80dp" android:layout_height="40dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="172dp" android:layout_marginTop="72dp"
android:gravity="center" android:gravity="center"
android:textColor="@color/red" android:textColor="@color/red"
android:textSize="18sp" android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" /> app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message">
<TextView
android:id="@+id/tv_device_messages"
style="@style/title1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/black"
android:textSize="11sp"
android:visibility="gone" />
</ScrollView>
<Button <Button
android:visibility="gone" android:visibility="gone"
android:id="@+id/btn_digitalCard" android:id="@+id/btn_digitalCard"

View File

@@ -1,36 +1,9 @@
<!-- SlideshowFragment layout --> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.dashboard.SlideshowFragment"> tools:context="com.example.hpostesting.presentation.dashboard.SlideshowFragment">
<TextView </androidx.constraintlayout.widget.ConstraintLayout>
android:visibility="gone"
android:id="@+id/text_slideshow"
style="@style/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:textAlignment="center"
android:textSize="20sp"
android:text="@string/to_be_launched_in_next_version_of_the_app"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Language Settings -->
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/text_slideshow"
app:layout_constraintBottom_toBottomOf="parent">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -255,5 +255,9 @@
<string name="place_sample">सैम्पल रखें</string> <string name="place_sample">सैम्पल रखें</string>
<string name="invalid">अमान्य</string> <string name="invalid">अमान्य</string>
<string name="error">त्रुटि</string> <string name="error">त्रुटि</string>
<string name="language_update">भाषा सफलतापूर्वक अपडेट की गई है</string>
<string name="select_language">अपनी पसंदीदा भाषा का चयन करें</string>
<string name="app_language">ऐप भाषा</string>
<string name="add_blood_group">रक्त समूह जोड़ें</string>
<string name="ok">ठीक है</string>
</resources> </resources>

View File

@@ -170,7 +170,7 @@
<string name="aadhaar_in_tv"><b>ಆಧಾರ್ ಸಂಖ್ಯೆ</b></string> <string name="aadhaar_in_tv"><b>ಆಧಾರ್ ಸಂಖ್ಯೆ</b></string>
<string name="please_use_official_abha_app_to_create_abha_id_and_come_back">ದಯವಿಟ್ಟು "ಆಧಿಕಾರಿ ABHA ಆಪ್" ಅನ್ನು ಬಳಸಿ ABHA ಐಡಿ ರಚಿಸಿ ಮತ್ತು ಹಿಂತಿರುಗಿ ಬನ್ನಿ.</string> <string name="please_use_official_abha_app_to_create_abha_id_and_come_back">ದಯವಿಟ್ಟು "ಆಧಿಕಾರಿ ABHA ಆಪ್" ಅನ್ನು ಬಳಸಿ ABHA ಐಡಿ ರಚಿಸಿ ಮತ್ತು ಹಿಂತಿರುಗಿ ಬನ್ನಿ.</string>
<string name="please_enter_aadhaar">ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</string> <string name="please_enter_aadhaar">ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</string>
<string name="scan_qr_code_of_the_kit">ಕಿಟ್ ಯಾವಾಗಲೂ QR ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string> <string name="scan_qr_code_of_the_kit">ಕಿಟ್‌ನ ಕ್ಯೂಆರ್ ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string>
<string name="enter_kit_serial_number_manually">ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string> <string name="enter_kit_serial_number_manually">ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string>
<string name="serial_number">ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ</string> <string name="serial_number">ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ</string>
<string name="set_baseline_reference_again">ಬೇಸ್ಲೈನ್/ಸಂದರ್ಭ ಹೊಂದಿಸಿರಾ?</string> <string name="set_baseline_reference_again">ಬೇಸ್ಲೈನ್/ಸಂದರ್ಭ ಹೊಂದಿಸಿರಾ?</string>
@@ -255,5 +255,11 @@
<string name="place_sample">ನಮೂನೆ ಇಟ್ಟುಕೊಳ್ಳಿ</string> <string name="place_sample">ನಮೂನೆ ಇಟ್ಟುಕೊಳ್ಳಿ</string>
<string name="invalid">ಅಮಾನ್ಯ</string> <string name="invalid">ಅಮಾನ್ಯ</string>
<string name="error">ದೋಷ</string> <string name="error">ದೋಷ</string>
<string name="language_update">ಭಾಷೆ ಯಶಸ್ವಿಯಾಗಿ ನವೀಕರಿಸಲಾಗಿದೆ</string>
<string name="select_language">ನಿಮ್ಮ ಆದರಿತ ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string>
<string name="app_language">ಅಪ್ಲಿಕೇಶನ್ ಭಾಷೆ</string>
<string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string>
<string name="ok">ಸರಿ</string>
<!-- Add translations for other strings -->
</resources> </resources>

View File

@@ -155,6 +155,7 @@
<string name="is_patient_married_yes_no">Is Patient Married? (Yes/No)</string> <string name="is_patient_married_yes_no">Is Patient Married? (Yes/No)</string>
<string name="category">Category</string> <string name="category">Category</string>
<string name="blood_group">Blood Group</string> <string name="blood_group">Blood Group</string>
<string name="add_blood_group">Add Blood Group</string>
<string name="digital_card">Digital Counselling Card</string> <string name="digital_card">Digital Counselling Card</string>
<string name="patient_medical_records">Patient Medical Records</string> <string name="patient_medical_records">Patient Medical Records</string>
<string name="patient_address_details">Patient Address Details</string> <string name="patient_address_details">Patient Address Details</string>
@@ -251,9 +252,13 @@
<string name="sample_started">Sample Started</string> <string name="sample_started">Sample Started</string>
<string name="buffer_completed">Buffer Completed</string> <string name="buffer_completed">Buffer Completed</string>
<string name="buffer_started">Buffer Started</string> <string name="buffer_started">Buffer Started</string>
<string name="power_bank">Connect with Power Bank</string>
<string name="start">Start</string> <string name="start">Start</string>
<string name="place_sample">Place Sample</string> <string name="place_sample">Place Sample</string>
<string name="invalid">Invalid</string> <string name="invalid">Invalid</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="language_update">Language updated successfully</string>
<string name="select_language">Select your preferred language</string>
<string name="app_language">App Language</string>
<string name="ok">OK</string>
</resources> </resources>

View File

@@ -9,7 +9,7 @@
<!-- <usb-device vendor-id="1027" product-id="24592" /> &lt;!&ndash; 0x6010: FT2232H &ndash;&gt;--> <!-- <usb-device vendor-id="1027" product-id="24592" /> &lt;!&ndash; 0x6010: FT2232H &ndash;&gt;-->
<!-- <usb-device vendor-id="1027" product-id="24593" /> &lt;!&ndash; 0x6011: FT4232H &ndash;&gt;--> <!-- <usb-device vendor-id="1027" product-id="24593" /> &lt;!&ndash; 0x6011: FT4232H &ndash;&gt;-->
<!-- <usb-device vendor-id="1027" product-id="24596" /> &lt;!&ndash; 0x6014: FT232H &ndash;&gt;--> <!-- <usb-device vendor-id="1027" product-id="24596" /> &lt;!&ndash; 0x6014: FT232H &ndash;&gt;-->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD --> <usb-device vendor-id="1027" product-id="24577" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x6015: FT230X, FT231X, FT234XD --> <usb-device vendor-id="6790" product-id="29987" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<!-- 0x10C4 / 0xEA??: Silabs CP210x --> <!-- 0x10C4 / 0xEA??: Silabs CP210x -->