Compare commits

..

136 Commits

Author SHA1 Message Date
chandrashekhar reddy
372489330a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 15:20:49 +05:30
chandrashekhar reddy
0c10e5a920 Merge remote-tracking branch 'origin/dev' into dev 2024-03-09 12:27:22 +05:30
chandrashekhar reddy
045bda26ff Rearranging the project structure, so it will east to understand and following proper clean code rules 2024-03-09 12:26:59 +05:30
Mariya
b31e5e6c06 removed getting null values from result upload 2024-03-07 13:30:38 +05:30
Mariya
53c36d3cf9 added different id and set as primary key for testing twice with same sample Id and uploading the result, offline ,issue fixed, and set ADMIN as user that can only download and export CSV file, for collecting user Data 2024-03-07 12:11:27 +05:30
chandrashekhar reddy
f922f585b5 Merge remote-tracking branch 'origin/dev' into dev 2024-03-05 14:46:12 +05:30
chandrashekhar reddy
1742363f1a added deviceUpdateGlobal field in HomeFragment 2024-03-05 14:45:47 +05:30
Mariya
ba9564d867 added new kit button and logout button for offline test 2024-03-05 14:44:06 +05:30
Mariya
1aaf2ba485 sanitize the results values if the result is NaN or infinity 2024-03-04 18:02:07 +05:30
Mariya
85756a7052 commented code for unregistereceiver 2024-03-04 16:47:55 +05:30
Mariya Varghese
0141c2791e Merge branch 'dev-check-apk-update' into 'dev'
app update and other api calls managing for molbio

See merge request sminnovations/hpos!39
2024-03-04 11:12:21 +00:00
Mariya Varghese
a52538e72d Merge branch 'dev' into 'dev-check-apk-update'
# Conflicts:
#   app/build.gradle
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt
#   build.gradle
#   gradle/wrapper/gradle-wrapper.properties
2024-03-04 11:11:13 +00:00
chandrashekhar reddy
78cc79eef8 changes in HomeFragment added deviceId global and added default values 2024-03-04 15:37:32 +05:30
Mariya
c9d0c440e3 added code for sanitize result upload values if if the result is NAN or infinity for molbio integration 2024-03-04 14:48:43 +05:30
chandrashekhar reddy
99da2fc094 error in HomeFragment and DashboardActivity solved registering broadcast receiver was giving issue solved by adding checks 2024-03-04 14:26:44 +05:30
Mariya
20f408230e api calls managing, and error resolving for molbio 2024-03-02 19:37:24 +05:30
Mariya
c8d5d41c81 api calls maintaining for molbio 2024-03-02 15:41:17 +05:30
Mariya
210c9fed5d added code for usb permission 2024-03-01 16:21:27 +05:30
chandrashekhar reddy
e947d083fb merge 2024-03-01 14:08:49 +05:30
Mariya
b68ec45642 reduced number of api calls in home screen 2024-03-01 13:37:16 +05:30
Mariya
1e5afa0a5c reduced number api calls for bigtec 2024-03-01 12:38:19 +05:30
Mariya
80ab69c772 added code for uploading logs only once 2024-02-29 14:18:09 +05:30
Pritimay Sarkar
2e1c932e72 auto switch baud rate between old and new devices 2024-02-29 14:01:23 +05:30
chandrashekhar reddy
6474181664 gpg error 2024-02-29 12:41:12 +05:30
Pritimay Sarkar
a142717ef2 fix pipeline 2024-02-29 12:09:39 +05:30
Pritimay Sarkar
0d72a0f6f1 add toast to usb listener 2024-02-29 11:15:45 +05:30
Pritimay Sarkar
63b51b1526 Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-29 10:16:25 +05:30
Pritimay Sarkar
95533aab0d add exception handling 2024-02-29 10:14:16 +05:30
Mariya
f7dc879c75 added code related offline bulkupload 2024-02-28 15:17:36 +05:30
Mariya
e8b5d12db5 removed unwanted toast messages 2024-02-28 15:12:21 +05:30
Mariya
626dd380ab Apk update successfully added 2024-02-28 14:46:06 +05:30
chandrashekhar reddy
c8677bc2bb gpg setup 2024-02-28 12:20:34 +05:30
Mariya
70b0b93f57 Apk Update Code Added 2024-02-27 20:44:32 +05:30
Mariya
5cdc156f33 Apk Update Code Added 2024-02-27 16:49:25 +05:30
Mariya
71d298cd69 Apk Update Code Added 2024-02-27 14:59:03 +05:30
chandrashekhar reddy
c48c5a1ae3 update without app distribution done 2024-02-27 14:18:46 +05:30
chandrashekhar reddy
97cc281752 Merge remote-tracking branch 'origin/dev' into dev 2024-02-27 14:00:01 +05:30
chandrashekhar reddy
4f6d3fa203 update without app distribution done 2024-02-27 13:59:30 +05:30
Mariya
bb6f4ee859 Apk Update Code Added 2024-02-27 12:43:14 +05:30
Pritimay Sarkar
4272e36385 refactoring unit tests 2024-02-26 20:28:24 +05:30
Pritimay Sarkar
eb1c764551 change thresholds 2024-02-23 09:36:01 +05:30
Pritimay Sarkar
cd593bb67b add unit test 2024-02-21 22:05:09 +05:30
Pritimay Sarkar
69ebb2f343 add release folder to gitignore 2024-02-21 22:04:48 +05:30
Pritimay Sarkar
3ddad93a6a add readme 2024-02-21 22:04:14 +05:30
Mariya
f0d71b3167 Merge remote-tracking branch 'origin/dev' into dev 2024-02-21 19:19:40 +05:30
Mariya
ab810e788b added keystore 2024-02-21 19:19:19 +05:30
Pritimay Sarkar
1bc8b18669 add borderline method 2 based on led2Average 2024-02-21 17:49:31 +05:30
Pritimay Sarkar
ea21c5d862 Merge branch 'ujjain' into 'dev'
Ujjain - add borderline metric

See merge request sminnovations/hpos!38
2024-02-20 15:12:58 +00:00
Pritimay Sarkar
3bad0720e3 add users 2024-02-20 10:52:05 +05:30
Pritimay Sarkar
b1342580ea avoid saving deviceid to pref 2024-02-20 10:50:42 +05:30
Pritimay Sarkar
d4c66e5e1a refactor code 2024-02-19 23:15:42 +05:30
Pritimay Sarkar
14516cad5f change binding logic 2024-02-19 23:14:42 +05:30
Pritimay Sarkar
a384c3e93a Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-19 11:01:19 +05:30
Pritimay Sarkar
8910e2978f hide device messages by default 2024-02-18 14:46:36 +05:30
Pritimay Sarkar
3bab859d0b update packages 2024-02-18 14:42:43 +05:30
Mariya
b036ae8377 getting null values in solution and concentration as name in firebase issue solved 2024-02-17 14:11:02 +05:30
Pritimay Sarkar
c91657c529 unit tests for lower and uppper bounds 2024-02-17 09:43:14 +05:30
Pritimay Sarkar
e64aa27f8a refine borderline 2024-02-17 09:09:45 +05:30
Pritimay Sarkar
515d154e50 remove a state check 2024-02-16 20:48:48 +05:30
Pritimay Sarkar
09d4bb56fc call print once 2024-02-16 18:51:57 +05:30
Pritimay Sarkar
d502e88da4 fix state atutomation 2024-02-16 14:50:39 +05:30
Pritimay Sarkar
f2d6916aa6 add borderline metric 2024-02-16 14:27:40 +05:30
Pritimay Sarkar
6e46c31bfc typo 2024-02-16 09:49:04 +05:30
Pritimay Sarkar
7986f22da1 fix pipeline 2024-02-16 09:48:20 +05:30
Pritimay Sarkar
b3726d8a9b Merge remote-tracking branch 'origin/Diagnostics' into dev 2024-02-16 09:33:53 +05:30
Pritimay Sarkar
cf899c187e Merge remote-tracking branch 'origin/dev-Issue-Fix-Branch' into dev 2024-02-16 09:30:52 +05:30
Pritimay Sarkar
e2bf442651 Merge remote-tracking branch 'origin/dev-assurance-empty-check' into dev 2024-02-16 09:28:48 +05:30
Pritimay Sarkar
3e8542e309 fix 2024-02-16 09:23:01 +05:30
Pritimay Sarkar
8c3b63390c show messages 2024-02-16 08:53:33 +05:30
Pritimay Sarkar
a984e6bf29 add device ids 2024-02-16 08:28:29 +05:30
Pritimay Sarkar
e227289cd9 fix eprom set command 2024-02-16 08:14:24 +05:30
Pritimay Sarkar
7aae2295a3 fix button 2024-02-15 23:34:32 +05:30
Pritimay Sarkar
582f08f8da add command to read current dac values 2024-02-15 23:27:14 +05:30
Pritimay Sarkar
efe60ab172 add command to set DAC values to eprom 2024-02-15 23:19:56 +05:30
Pritimay Sarkar
b53e20682d pipeline related change 2024-02-15 23:00:49 +05:30
Pritimay Sarkar
dc2a0849b9 add EPROM retrival 2024-02-15 22:56:07 +05:30
Mariya
4ba3b98d2d updated date format, to check is getting null values 2024-02-15 20:55:34 +05:30
Mariya
c379d68679 errors fixed in Repository file 2024-02-15 20:49:29 +05:30
Mariya
0858fc5da0 errors fixed in Repository file 2024-02-14 18:06:25 +05:30
Mariya Varghese
db317bf126 Merge branch 'dev' into 'Diagnostics'
# Conflicts:
#   app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt
#   app/src/main/java/com/example/hpostesting/data/repository/Repository.kt
2024-02-14 11:40:46 +00:00
Mariya
fe3f17b71d Message format is changed 2024-02-14 17:01:30 +05:30
Mariya
b5f605157e Device Diagnostics Api structure done successfully Added, 2024-02-14 17:00:18 +05:30
Mariya
ab1208d9ee Device Diagnostics Api structure done successfully 2024-02-14 15:53:38 +05:30
Pritimay Sarkar
b0bbae7cfa clean code 2024-02-14 14:13:00 +05:30
Pritimay Sarkar
a4ae03a2a7 refactoring 2024-02-14 12:47:39 +05:30
Mariya
8e5294f564 Disable Download Csv button 2024-02-13 18:54:04 +05:30
Pritimay Sarkar
f5068c70c2 build file change for pipeline 2024-02-13 17:59:26 +05:30
Pritimay Sarkar
8019ed2c30 add refresh and qr code scan - jig 2024-02-13 17:57:38 +05:30
Pritimay Sarkar
6afee91d27 add test jig screen 2024-02-13 14:30:21 +05:30
Mariya
547cf714a4 Toast message changed in KitScanActivity if the Scanner is not available 2024-02-13 13:02:21 +05:30
Mariya
fd5fb6db22 text view removed of "all registers are tested" for offline, its its only display if the internet is available 2024-02-13 12:57:41 +05:30
Mariya
9b2b64f248 Added Scroll view for the panel screen 2024-02-13 12:47:57 +05:30
Pritimay Sarkar
830eb525fd add kit capacity in constants 2024-02-13 12:44:02 +05:30
Pritimay Sarkar
06241008f1 rounded corners logo 2024-02-13 09:00:29 +05:30
Pritimay Sarkar
0721be0114 save nats token in backend 2024-02-13 08:59:28 +05:30
Pritimay Sarkar
23cf38445f handle method and dynamic config for NATS 2024-02-13 08:59:03 +05:30
Pritimay Sarkar
6577842ba9 add dynamic topic based on deviceId 2024-02-13 00:07:05 +05:30
Pritimay Sarkar
c52d9835cd refactor and fix pipeline 2024-02-12 22:16:17 +05:30
Pritimay Sarkar
9f04125f68 fix conflict 2024-02-12 18:07:19 +05:30
Pritimay Sarkar
2b2c16df22 Merge remote-tracking branch 'origin/device-provision-response-store' into dev 2024-02-12 18:04:58 +05:30
Pritimay Sarkar
727040fabf Merge remote-tracking branch 'origin/dev-bulk-upload' into dev 2024-02-12 18:01:38 +05:30
Mariya
80eb658b07 changes when we tested 2024-02-12 17:56:37 +05:30
Mariya
8c9903c759 changes added for bulkupload the devices 2024-02-12 16:57:56 +05:30
Mariya
9314b155cd Device provision fetching code is added 2024-02-12 13:56:05 +05:30
Mariya
7f47e1dff8 Device provision username and password stored in firebase store separately 2024-02-12 12:01:10 +05:30
Pritimay Sarkar
be21430d0a Merge remote-tracking branch 'origin/nats_certificate_download' into dev 2024-02-11 14:08:00 +05:30
Mariya
d5b6910408 Device provision response storing 2024-02-10 17:37:07 +05:30
Pritimay Sarkar
3609d728c1 release 2.1.110 2024-02-10 12:18:52 +05:30
Pritimay Sarkar
7302ad669f release 2.1.108 2024-02-10 11:10:06 +05:30
Pritimay Sarkar
ef98b09eaf release 2.1.107 2024-02-10 10:46:54 +05:30
Mariya
89dc7f7234 Added code related to device provision fetching fromfirestore 2024-02-09 16:39:02 +05:30
Pritimay Sarkar
f631a273d7 TLS impleamentation on NATS server 2024-02-09 13:50:33 +05:30
Pritimay Sarkar
de74da3135 add package name dynamically in provider 2024-02-09 13:49:16 +05:30
Mariya
dd1144d884 Molbio Flags are updated 2024-02-08 20:48:26 +05:30
Mariya
37c8dde5bd Added code in manifest file for launcher 2024-02-08 15:44:27 +05:30
Mariya
5f460f6aa3 Added code for firefox and Files redirection 2024-02-08 15:30:51 +05:30
Pritimay Sarkar
ad625992a7 fix pipeline 2024-02-08 14:41:27 +05:30
Mariya
c5cb8a0983 Added code for fetching response of device provision api from firebase 2024-02-08 14:24:34 +05:30
Pritimay Sarkar
db518007b3 Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-08 12:33:49 +05:30
Pritimay Sarkar
4d09bad516 log addititonal data in diagnostics and auto dac 2024-02-08 12:33:36 +05:30
Mariya
6ddb491bc8 Added code to send response of device provision api into firebase 2024-02-08 12:18:31 +05:30
Mariya
aad33e3907 Merge remote-tracking branch 'origin/dev' into dev 2024-02-08 11:59:06 +05:30
Mariya
52279c4419 code removed from manifest for molbio 2024-02-08 11:58:45 +05:30
Mariya
c5c0467e42 code added to store device provision response 2024-02-08 11:48:35 +05:30
Pritimay Sarkar
190a72e407 Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-07 17:19:33 +05:30
Mariya
466d0e2afc code added related to nats 2024-02-07 16:33:57 +05:30
Pritimay Sarkar
4aa6fb020b display device ratio and slope ratio 2024-02-07 16:25:34 +05:30
Mariya
044a545979 code added in manifest file 2024-02-07 13:01:09 +05:30
Mariya
45fd4861f4 nats code 2024-02-07 12:49:31 +05:30
Mariya
1f9f8060cb manifest file changes and drawable file added for release apk 2024-02-06 16:48:19 +05:30
Mariya
1a3bb67dce nats 2024-02-06 16:23:33 +05:30
Mariya
8bc9b1449f Added code for Device Diagnostics 2024-02-06 15:17:46 +05:30
Mariya
7e5228bb35 Added code for Device Diagnostics 2024-02-06 14:53:35 +05:30
Pritimay Sarkar
4fef75b937 add new thresholds with additonal method and unit tests 2024-02-06 13:44:00 +05:30
Mariya
3dd247b15d Nats Certificate Download API is completed 2024-02-06 13:25:06 +05:30
Mariya
42b33c9397 Added code for scan , Issue fixed 2024-02-05 17:23:33 +05:30
152 changed files with 3992 additions and 1187 deletions

3
.idea/gradle.xml generated
View File

@@ -4,9 +4,8 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

4
README.md Normal file
View File

@@ -0,0 +1,4 @@
### Release key
key0: prime24

1
app/.gitignore vendored
View File

@@ -1,3 +1,4 @@
/build /build
/release
/google-services* /google-services*
/idea /idea

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, dev - development // dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting.quality" applicationId "in.sminnovations.hpostesting.dev"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 99 versionCode 120
versionName "2.1.99" versionName "2.1.120"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -80,16 +80,16 @@ dependencies {
implementation 'com.google.firebase:firebase-auth-ktx' implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx' implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2' implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.google.android.gms:play-services-auth:20.7.0' implementation 'com.google.android.gms:play-services-auth:21.0.0'
implementation 'com.google.android.gms:play-services-location:21.1.0' implementation 'com.google.android.gms:play-services-location:21.1.0'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0' implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta11' implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta12'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta11") implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta12")
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'com.google.android.play:core:1.10.3' implementation 'com.google.android.play:core:1.10.3'
implementation 'io.nats:jnats:2.11.2' implementation 'io.nats:jnats:2.11.4'
@@ -143,8 +143,8 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
// Navigation Component // Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.6" implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
implementation "androidx.navigation:navigation-ui-ktx:2.7.6" implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
//Dagger - Hilt //Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46" implementation "com.google.dagger:hilt-android:2.46"
@@ -157,7 +157,7 @@ dependencies {
implementation("com.squareup.okhttp3:okhttp:4.9.3") implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation "androidx.preference:preference-ktx:1.2.1" implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'io.nats:jnats:2.11.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1'
implementation("androidx.work:work-runtime-ktx:2.9.0") implementation("androidx.work:work-runtime-ktx:2.9.0")
@@ -165,4 +165,6 @@ dependencies {
implementation 'com.google.android.play:core:1.10.3' implementation 'com.google.android.play:core:1.10.3'
implementation fileTree(dir: 'libs', include: ['*.aar']) implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation 'io.nats:jnats:2.11.4'
} }

View File

@@ -1,45 +1,205 @@
{ {
"project_info": { "project_info": {
"project_number": "1004619739289", "project_number": "650071678820",
"project_id": "hpos-qa", "project_id": "hpos-af3cc",
"storage_bucket": "hpos-qa.appspot.com" "storage_bucket": "hpos-af3cc.appspot.com"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:1004619739289:android:f669b47552748433e5c808", "mobilesdk_app_id": "1:650071678820:android:f1435a1c07f710036c6471",
"android_client_info": { "android_client_info": {
"package_name": "in.sminnovations.hposregistration.quality" "package_name": "com.example.hposconsentform"
} }
}, },
"oauth_client": [], "oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs" "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
} }
], ],
"services": { "services": {
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [] "other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
} }
} }
}, },
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:1004619739289:android:8397cd1f0357bd89e5c808", "mobilesdk_app_id": "1:650071678820:android:7865bef608cdee6f6c6471",
"android_client_info": { "android_client_info": {
"package_name": "in.sminnovations.hpostesting.quality" "package_name": "com.smi.counselling"
} }
}, },
"oauth_client": [], "oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs" "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
} }
], ],
"services": { "services": {
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [] "other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:2925e9ce3417d2386c6471",
"android_client_info": {
"package_name": "in.sminnovations.hemocube"
}
},
"oauth_client": [
{
"client_id": "650071678820-srhm9spm9hjn4frcd3r6o02gdhdbtd15.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hemocube",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:7569c1cad4fc99916c6471",
"android_client_info": {
"package_name": "in.sminnovations.hposregistration"
}
},
"oauth_client": [
{
"client_id": "650071678820-70kp5jvjda4r5diqch2kn4lc40p4f42g.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hposregistration",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:f96be19e5d43102b6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting"
}
},
"oauth_client": [
{
"client_id": "650071678820-l87dnr0bdj95get0khgnvfv2an1k6ogq.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hpostesting",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:a53292637abb7c0d6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting.dev"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
} }
} }
} }

Binary file not shown.

View File

@@ -4,15 +4,15 @@
"type": "APK", "type": "APK",
"kind": "Directory" "kind": "Directory"
}, },
"applicationId": "com.example.hpos", "applicationId": "in.sminnovations.hpostesting.quality",
"variantName": "release", "variantName": "release",
"elements": [ "elements": [
{ {
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"attributes": [], "attributes": [],
"versionCode": 1, "versionCode": 101,
"versionName": "1.0", "versionName": "2.1.101",
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }
], ],

View File

@@ -25,6 +25,7 @@
<application <application
android:name="com.example.hpostesting.HPOSTestingApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:largeHeap="true"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
@@ -48,6 +49,10 @@
android:name="com.example.hpostesting.presentation.autodac.AutoDacActivity" android:name="com.example.hpostesting.presentation.autodac.AutoDacActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.jig.JigActivity"
android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity <activity
android:name="com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity" android:name="com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity"
android:exported="false" android:exported="false"
@@ -95,6 +100,7 @@
android:exported="false" android:exported="false"
android:label="@string/title_activity_dashboard" android:label="@string/title_activity_dashboard"
android:theme="@style/Theme.HPOS.NoActionBar" android:theme="@style/Theme.HPOS.NoActionBar"
android:screenOrientation="portrait"
tools:ignore="AppLinkUrlError,MissingClass"> tools:ignore="AppLinkUrlError,MissingClass">
<intent-filter> <intent-filter>
@@ -118,9 +124,8 @@
android:noHistory="true" android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
@@ -157,10 +162,10 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:stateNotNeeded="true" android:stateNotNeeded="true"
tools:replace="android:screenOrientation" /> tools:replace="android:screenOrientation" />
<!-- ${applicationId}-->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="com.example.hpostesting.fileprovider" android:authorities="${applicationId}.fileprovider"
android:exported="false" android:exported="false"
android:grantUriPermissions="true"> android:grantUriPermissions="true">
<meta-data <meta-data

View File

@@ -1,20 +1,15 @@
package com.example.hpostesting package com.example.hpostesting
import android.app.Application import android.app.Application
import android.content.Context
import androidx.room.Room
import com.example.hpostesting.data.dao.MyDatabase
import com.google.android.datatransport.runtime.dagger.Provides
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.FirebaseFirestoreSettings import com.google.firebase.firestore.FirebaseFirestoreSettings
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@HiltAndroidApp @HiltAndroidApp
class HPOSTestingApplication: Application() { class HPOSTestingApplication : Application() {
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreate() { override fun onCreate() {

View File

@@ -1,5 +1,7 @@
package com.example.hpostesting.data.api package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginRequest
@@ -11,11 +13,12 @@ interface MolbioAuthApi {
@POST("deviceManagement/device/provision") @POST("deviceManagement/device/provision")
suspend fun deviceProvision( suspend fun deviceProvision(
@Body deviceProvisionRequest: DeviceProvisionRequest @Body deviceProvisionRequest: DeviceProvisionRequest,
): DeviceProvisionResponse ): DeviceProvisionResponse
@POST("deviceService/device/login") @POST("deviceService/device/login")
suspend fun login( suspend fun login(
@Body loginRequest: LoginRequest @Body loginRequest: LoginRequest,
): LoginResponse ): LoginResponse
} }

View File

@@ -1,5 +1,7 @@
package com.example.hpostesting.data.api package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
import com.example.hpostesting.data.model.log.UploadLogsResponse import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse
@@ -9,6 +11,7 @@ import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.ResponseBody import okhttp3.ResponseBody
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Multipart import retrofit2.http.Multipart
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.PUT import retrofit2.http.PUT
@@ -18,22 +21,32 @@ interface MolbioResultApi {
@PUT("deviceService/results/HPOS") @PUT("deviceService/results/HPOS")
suspend fun uploadResults( suspend fun uploadResults(
@Body molbioV2ResultRequest: MolbioV2ResultRequest @Body molbioV2ResultRequest: MolbioV2ResultRequest,
): MolbioV2ResultResponse ): MolbioV2ResultResponse
@POST("deviceService/device/checkUpdate") @POST("deviceService/device/checkUpdate")
suspend fun checkUpdate( suspend fun checkUpdate(
@Body checkUpdateRequest: CheckUpdateRequest @Body checkUpdateRequest: CheckUpdateRequest,
): CheckUpdateResponse ): CheckUpdateResponse
@POST("deviceService/device/getUpdate") @POST("deviceService/device/getUpdate")
suspend fun deviceUpdate( suspend fun deviceUpdate(
@Body deviceUpdateRequest: DeviceUpdateRequest @Body deviceUpdateRequest: DeviceUpdateRequest,
): ResponseBody
@GET("deviceService/device/getClientCertificate")
suspend fun downloadClientCertificate(
): ResponseBody ): ResponseBody
@Multipart @Multipart
@POST("deviceService/device/uploadLogs") @POST("deviceService/device/uploadLogs")
suspend fun uploadLogs( suspend fun uploadLogs(
@Part logFile: MultipartBody.Part @Part logFile: MultipartBody.Part,
): UploadLogsResponse ): UploadLogsResponse
@PUT("deviceService/device/uploadDeviceDiagnostics")
suspend fun deviceDiagnostics(
@Body deviceDiagnosticsRequest: DeviceDiagnosticsRequest
): DeviceDiagnosticsResponse
} }

View File

@@ -5,10 +5,10 @@ object Constants {
const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION" const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION"
const val BASE_URL = "www.google.com" const val BASE_URL = "www.google.com"
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr" const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTERGATION = false const val MOLBIO_INTEGRATION = true
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in" const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69" const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI" const val DEVICE_ID_API = "deviceIDAPI"
@@ -61,9 +61,14 @@ object Constants {
const val BLANK_EVERY_TEST = false const val BLANK_EVERY_TEST = false
// jig
const val NAVIGATE_TO_TEST_JIG_DIRECTLY = false
val STATICID = listOf( val STATICID = listOf(
"FACTORY", "FACTORY",
"ADMIN", "ADMIN",
"PQUSER",
"QCUSER",
"VIZ-1000-0004", "VIZ-1000-0004",
"VIZ-1000-0005", "VIZ-1000-0005",
"VIZ-1000-0006", "VIZ-1000-0006",
@@ -167,12 +172,64 @@ object Constants {
"HPP1-0124-0048", "HPP1-0124-0048",
"HPP1-0124-0049", "HPP1-0124-0049",
"HPP1-0124-0050", "HPP1-0124-0050",
"HCV-001-0001",
"HCV-001-0002",
"HCV-001-0003",
"HCV-001-0004",
"HCV-001-0005",
"HCV-001-0006",
"HCV-001-0007",
"HCV-001-0008",
"HCV-001-0009",
"HCV-001-0010",
"HCV-001-0011",
"HCV-001-0012",
"HCV-001-0013",
"HCV-001-0014",
"HCV-001-0015",
"HCV-001-0016",
"HCV-001-0017",
"HCV-001-0018",
"HCV-001-0019",
"HCV-001-0020",
"HCV-001-0021",
"HCV-001-0022",
"HCV-001-0023",
"HCV-001-0024",
"HCV-001-0025",
"HCV-001-0026",
"HCV-001-0027",
"HCV-001-0028",
"HCV-001-0029",
"HCV-001-0030",
"HCV-001-0031",
"HCV-001-0032",
"HCV-001-0033",
"HCV-001-0034",
"HCV-001-0003",
"HCV-001-0035",
"HCV-001-0036",
"HCV-001-0037",
"HCV-001-0038",
"HCV-001-0039",
"HCV-001-0040",
"HCV-001-0041",
"HCV-001-0042",
"HCV-001-0043",
"HCV-001-0044",
"HCV-001-0045",
"HCV-001-0046",
"HCV-001-0047",
"HCV-001-0048",
"HCV-001-0049",
"HCV-001-0050",
) )
const val password = "SMI@12345" const val password = "SMI@12345"
const val KIT_NUMBER = "KitNumber" const val KIT_NUMBER = "KitNumber"
const val KIT_COUNT = "KitCount" const val KIT_COUNT = "KitCount"
const val KIT_CAPACITY = Int.MAX_VALUE // Enforceable
const val BUFFER_VALUE_1 = "BufferValue1" const val BUFFER_VALUE_1 = "BufferValue1"
const val BUFFER_VALUE_2 = "BufferValue2" const val BUFFER_VALUE_2 = "BufferValue2"
const val BUFFER_VALUE_3 = "BufferValue3" const val BUFFER_VALUE_3 = "BufferValue3"
@@ -182,19 +239,6 @@ object Constants {
const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_LOWER_BOUND = 21000
const val BUFFER_LED_UPPER_BOUND = 23500 const val BUFFER_LED_UPPER_BOUND = 23500
const val TEST_STATUS_CODE_TEST_STARTED = 1.0
const val TEST_STATUS_CODE_CONFIG_STARTED = 2.0
const val TEST_STATUS_CODE_CONFIG_COMPLETED = 3.0
const val TEST_STATUS_CODE_BUFFER_STARTED = 4.0
const val TEST_STATUS_CODE_BUFFER_COMPLETED = 5.0
const val TEST_STATUS_CODE_BUFFER_PRINT_STARTED = 6.0
const val TEST_STATUS_CODE_BUFFER_PRINT_COMPLETED = 7.0
const val TEST_STATUS_CODE_SAMPLE_STARTED = 8.0
const val TEST_STATUS_CODE_SAMPLE_COMPLETED = 9.0
const val TEST_STATUS_CODE_SAMPLE_PRINT_STARTED = 10.0
const val TEST_STATUS_CODE_SAMPLE_PRINT_COMPLETED = 11.0
const val TEST_STATUS_CODE_TEST_COMPLETED = 12.0
val DEVICE_CONFIGURATION: Map<String, List<List<Double>>> = mapOf<String, List<List<Double>>>( 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.0, 0.0), // LED1, 435nm listOf(1.0, 0.0), // LED1, 435nm
@@ -1659,11 +1703,10 @@ object Constants {
) )
) )
val COEFFICIENTS: Map<String, List<List<Double>>> = mapOf( val COEFFICIENTS: Map<String, List<List<Double>>> = mapOf(
"HC-V1-005" to listOf( "HC-V1-005" to listOf(
listOf(1.5,0.0), listOf(1.5, 0.0),
listOf(0.0,0.0) listOf(0.0, 0.0)
) )
) )

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.data.constant
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData

View File

@@ -3,12 +3,14 @@ package com.example.hpostesting.data.constant
enum class HemoCubeCommands(val command: String) { enum class HemoCubeCommands(val command: String) {
START_BUFFER_COMMAND("B\r"), START_BUFFER_COMMAND("B\r"),
AUTO_DAC_COMMAND("C\r"), AUTO_DAC_COMMAND("C\r"),
SET_AUTO_DAC_TO_EPROM_COMMAND("G\r"),
DIAGNOSTICS_COMMAND("D\r"), DIAGNOSTICS_COMMAND("D\r"),
FIRMWARE_INFO_COMMAND("F\r"), FIRMWARE_INFO_COMMAND("F\r"),
START_SAMPLE("S\r"), START_SAMPLE("S\r"),
PRINT_COMMAND("P\r"), PRINT_COMMAND("P\r"),
READ_DAC_COMMAND("R\r"), READ_DAC_COMMAND("R\r"),
DEVICE_CONFIGURATION_COMMAND("I\r"), DEVICE_CONFIGURATION_COMMAND("I\r"),
LOAD_DAC_VALUES("E\r"),
FIRST_GAIN_COMMAND("T\r"), FIRST_GAIN_COMMAND("T\r"),
SECOND_GAIN_COMMAND("U\r"), SECOND_GAIN_COMMAND("U\r"),
THIRD_GAIN_COMMAND("V\r"), THIRD_GAIN_COMMAND("V\r"),

View File

@@ -19,12 +19,14 @@ object LanguageManager {
} }
fun persistLanguagePreference(context: Context, languageCode: String) { fun persistLanguagePreference(context: Context, languageCode: String) {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE) val prefs: SharedPreferences =
context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
prefs.edit().putString(LANGUAGE_PREF_KEY, languageCode).apply() prefs.edit().putString(LANGUAGE_PREF_KEY, languageCode).apply()
} }
fun getSavedLanguage(context: Context): String { fun getSavedLanguage(context: Context): String {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE) val prefs: SharedPreferences =
context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
return prefs.getString(LANGUAGE_PREF_KEY, "en") ?: "en" return prefs.getString(LANGUAGE_PREF_KEY, "en") ?: "en"
} }
} }

View File

@@ -8,7 +8,9 @@ enum class TestStatus(val code: Double) {
FIRST_EMPTY_AIR_READING_COMPLETED(4.2), FIRST_EMPTY_AIR_READING_COMPLETED(4.2),
FIRST_EMPTY_AIR_READING_PRINT_STARTED(4.3), FIRST_EMPTY_AIR_READING_PRINT_STARTED(4.3),
FIRST_EMPTY_AIR_READING_PRINT_COMPLETED(4.4), FIRST_EMPTY_AIR_READING_PRINT_COMPLETED(4.4),
BUFFER_STARTED(4.0), EPROM_ADC_RETRIEVAL_STARTED(4.5),
EPROM_ADC_RETRIEVAL_COMPLETED(4.6),
BUFFER_STARTED(4.7),
BUFFER_COMPLETED(5.0), BUFFER_COMPLETED(5.0),
BUFFER_PRINT_STARTED(6.0), BUFFER_PRINT_STARTED(6.0),
BUFFER_PRINT_COMPLETED(7.0), BUFFER_PRINT_COMPLETED(7.0),

View File

@@ -16,6 +16,7 @@ class Converters {
null null
} }
} }
@TypeConverter @TypeConverter
fun toString(location: UserData.Location?): String? { fun toString(location: UserData.Location?): String? {
return if (location != null) { return if (location != null) {

View File

@@ -7,7 +7,7 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
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
@Dao @Dao
interface DeviceDao { interface DeviceDao {
@Query("SELECT * from device_table") @Query("SELECT * from device_table")

View File

@@ -5,6 +5,7 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
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.UserData
@Dao @Dao
@@ -29,4 +30,8 @@ interface HemoCubeDao {
@Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id") @Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id")
suspend fun updateCSVFieldById(id: String, newValue: Boolean) suspend fun updateCSVFieldById(id: String, newValue: Boolean)
@Query("SELECT * from hemo_cube_test_table WHERE localFlag = 0")
fun getPendingUser(): LiveData<List<HemoCubeTestData>>
} }

View File

@@ -8,7 +8,11 @@ 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.UserData
@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class], version = 24, exportSchema = false) @Database(
entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class],
version = 29,
exportSchema = false
)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() { abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao

View File

@@ -1,11 +1,6 @@
package com.example.hpostesting.data.datasource package com.example.hpostesting.data.datasource
import android.os.Environment
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.opencsv.CSVWriter
import java.io.File
import java.io.FileWriter
import java.io.IOException
interface LocalFileDataSource { interface LocalFileDataSource {
@@ -14,6 +9,6 @@ interface LocalFileDataSource {
fun saveTextToDisk(filepath: String, contents: String) fun saveTextToDisk(filepath: String, contents: String)
fun exportDataToCSV( fun exportDataToCSV(
fileName: String, dataList: List<HemoCubeTestData> fileName: String, dataList: List<HemoCubeTestData>,
): Boolean ): Boolean
} }

View File

@@ -8,7 +8,7 @@ import java.io.FileWriter
import java.io.IOException import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
class LocalFileDataSourceImpl @Inject constructor(): LocalFileDataSource { class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
override fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) { override fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) {
val writer = CSVWriter(FileWriter(filepath)) val writer = CSVWriter(FileWriter(filepath))
@@ -25,10 +25,13 @@ class LocalFileDataSourceImpl @Inject constructor(): LocalFileDataSource {
} }
override fun exportDataToCSV( override fun exportDataToCSV(
fileName: String, dataList: List<HemoCubeTestData> fileName: String, dataList: List<HemoCubeTestData>,
): Boolean { ): Boolean {
try { try {
val formattedFileName = fileName.replace(Regex("[^a-zA-Z0-9.-]"), "_") // Replace special characters with underscores val formattedFileName = fileName.replace(
Regex("[^a-zA-Z0-9.-]"),
"_"
) // Replace special characters with underscores
val filePath = File(getExternalStorageDirectory(), formattedFileName) val filePath = File(getExternalStorageDirectory(), formattedFileName)
val writer = FileWriter(filePath) val writer = FileWriter(filePath)
val csvWriter = CSVWriter(writer) val csvWriter = CSVWriter(writer)
@@ -86,8 +89,9 @@ class LocalFileDataSourceImpl @Inject constructor(): LocalFileDataSource {
) )
csvWriter.writeNext(header) csvWriter.writeNext(header)
// Write data rows // Filter and write data rows where testStatus is true
for (data in dataList) { val filteredDataList = dataList.filter { it.testStatus == true }
for (data in filteredDataList) {
val row = arrayOf( val row = arrayOf(
data._id, data._id,
data.name, data.name,

View File

@@ -0,0 +1,14 @@
package com.example.hpostesting.data.model.devicediagnostics
data class AdditionalDetails(
val batteryLevel: String? = "",
val batteryCapacity: String? = "",
val batteryMaxCapacity: String? = "",
val batteryTemperature: String? = "",
val batteryVoltage: String? = "",
)

View File

@@ -0,0 +1,12 @@
package com.example.hpostesting.data.model.devicediagnostics
data class DeviceDiagnosticsData(
val id: String? = "",
val deviceId: String? = "",
val additionalDetails: AdditionalDetails?= AdditionalDetails(),
val createdBy: String? = "",
val updatedBy: String? = "",
val updatedAt: String? = "",
val createdAt: String? = "",
)

View File

@@ -0,0 +1,5 @@
package com.example.hpostesting.data.model.devicediagnostics
data class DeviceDiagnosticsRequest(
val additionalDetails: AdditionalDetails?= AdditionalDetails()
)

View File

@@ -0,0 +1,11 @@
package com.example.hpostesting.data.model.devicediagnostics
import com.google.gson.annotations.SerializedName
data class DeviceDiagnosticsResponse(
@SerializedName("Data")
val data: DeviceDiagnosticsData? = DeviceDiagnosticsData(),
val message: String? = "",
val result: String? = ""
)

View File

@@ -2,5 +2,5 @@ package com.example.hpostesting.data.model.deviceprovision
data class Credentials( data class Credentials(
val password: String? = "", val password: String? = "",
val username: String? = "" val username: String? = "",
) )

View File

@@ -13,5 +13,5 @@ data class Device(
val serialNumber: String? = "", val serialNumber: String? = "",
val uid: String? = "", val uid: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0 val updatedBy: Int? = 0,
) )

View File

@@ -2,5 +2,5 @@ package com.example.hpostesting.data.model.deviceprovision
data class DeviceProvisionData( data class DeviceProvisionData(
val credentials: Credentials? = Credentials(), val credentials: Credentials? = Credentials(),
val device: Device? = Device() val device: Device? = Device(),
) )

View File

@@ -5,5 +5,5 @@ data class DeviceProvisionRequest(
val email: String? = "", val email: String? = "",
val password: String? = "", val password: String? = "",
val serialNumber: String? = "", val serialNumber: String? = "",
val uid: String? = "" val uid: String? = "",
) )

View File

@@ -8,5 +8,5 @@ data class DeviceProvisionResponse(
@SerializedName("Message") @SerializedName("Message")
val message: String? = "", val message: String? = "",
@SerializedName("Result") @SerializedName("Result")
val result: String? = "" val result: String? = "",
) )

View File

@@ -8,5 +8,5 @@ data class DeviceType(
val id: Int? = 0, val id: Int? = 0,
val name: String? = "", val name: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0 val updatedBy: Int? = 0,
) )

View File

@@ -11,5 +11,5 @@ data class DeviceUser(
val natsTokenExpiry: String? = "", val natsTokenExpiry: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0, val updatedBy: Int? = 0,
val username: String? = "" val username: String? = "",
) )

View File

@@ -0,0 +1,8 @@
package com.example.hpostesting.data.model.deviceprovision
data class ProvisionData(
val username: String?,
val password: String?,
val natsToken: String?,
)

View File

@@ -1,9 +1,12 @@
package com.example.hpostesting.data.model.diagnostics package com.example.hpostesting.data.model.diagnostics
data class DiagnosticsData ( data class DiagnosticsData(
var deviceId: String = "", var deviceId: String = "",
var appVersion: String? = "", var appVersion: String? = "",
var deviceType: String = "HEMOCUBE", var deviceType: String = "HEMOCUBE",
var deviceData: String = "", var deviceData: String = "",
var runTime: String = "" var devicePassword: String = "",
var deviceNatsToken: String = "",
var accessToken: String = "",
var runTime: String = "",
) )

View File

@@ -0,0 +1,9 @@
package com.example.hpostesting.data.model.jig
data class JigData(
var deviceId: String = "",
var appVersion: String? = "",
var deviceType: String = "JIG",
var scanData: String = "",
var createdAt: String = "",
)

View File

@@ -1,5 +1,5 @@
package com.example.hpostesting.data.model.log package com.example.hpostesting.data.model.log
data class UploadLogsData( data class UploadLogsData(
val filename: String? = "" val filename: String? = "",
) )

View File

@@ -8,5 +8,5 @@ data class UploadLogsResponse(
@SerializedName("Message") @SerializedName("Message")
val message: String? = "", val message: String? = "",
@SerializedName("Result") @SerializedName("Result")
val result: String? = "" val result: String? = "",
) )

View File

@@ -12,5 +12,5 @@ data class Device(
val serialNumber: String? = "", val serialNumber: String? = "",
val uid: String? = "", val uid: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0 val updatedBy: Int? = 0,
) )

View File

@@ -8,5 +8,5 @@ data class DeviceType(
val id: Int? = 0, val id: Int? = 0,
val name: String? = "", val name: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0 val updatedBy: Int? = 0,
) )

View File

@@ -12,5 +12,5 @@ data class DeviceUser(
val natsTokenExpiry: String? = "", val natsTokenExpiry: String? = "",
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0, val updatedBy: Int? = 0,
val username: String? = "" val username: String? = "",
) )

View File

@@ -2,5 +2,5 @@ package com.example.hpostesting.data.model.login
data class LoginData( data class LoginData(
val accessToken: String? = "", val accessToken: String? = "",
val deviceUser: DeviceUser? = DeviceUser() val deviceUser: DeviceUser? = DeviceUser(),
) )

View File

@@ -9,5 +9,5 @@ data class LoginRequest(
val password: String? = "", val password: String? = "",
val serialNumber: String? = "", val serialNumber: String? = "",
val username: String? = "", val username: String? = "",
val version: String? = "" val version: String? = "",
) )

View File

@@ -8,5 +8,5 @@ data class LoginResponse(
@SerializedName("Message") @SerializedName("Message")
val message: String? = "", val message: String? = "",
@SerializedName("Result") @SerializedName("Result")
val result: String? = "" val result: String? = "",
) )

View File

@@ -4,7 +4,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
data class MolbioV2Result( data class MolbioV2Result(
val age: Int? = 31, val age: Int? = 31,
val analysisDate: String? = "", val analysisDate: String? = "2024-02-08 16:33:56",
val analysisId: String? = "", val analysisId: String? = "",
val analysisStatus: String? = "", val analysisStatus: String? = "",
val analysisType: String? = "HPOS", val analysisType: String? = "HPOS",
@@ -12,11 +12,11 @@ data class MolbioV2Result(
val bloodGroup: String? = "", val bloodGroup: String? = "",
val coefficients: List<Int>? = listOf(22, 22), val coefficients: List<Int>? = listOf(22, 22),
val collectionLocation: List<Any>? = listOf(), val collectionLocation: List<Any>? = listOf(),
val collectionTime: String? = "", val collectionTime: String? = "2024-02-08 16:33:56",
val collector: String? = "", val collector: String? = "",
val curveFitting: String? = "Linear", val curveFitting: String? = "Linear",
val deviceName: String? = "HPOS", val deviceName: String? = "HPOS",
val expiryTime: String? = "", val expiryTime: String? = "2024-02-08 16:33:56",
val gender: String? = "", val gender: String? = "",
val interpretation: String? = "", val interpretation: String? = "",
val `operator`: String? = "", val `operator`: String? = "",
@@ -30,9 +30,9 @@ data class MolbioV2Result(
val testId: String? = "", val testId: String? = "",
val testResult: String? = "", val testResult: String? = "",
val testStatus: String? = "", val testStatus: String? = "",
val testTime: String? = "", val testTime: String? = "2024-02-08 16:33:56",
val testType: String? = "", val testType: String? = "",
val thresholds: String? = "", val thresholds: String? = "",
val underMedication: Boolean? = false, val underMedication: Boolean? = false,
val volume: Int? = 2 val volume: Int? = 2,
) )

View File

@@ -4,20 +4,20 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
data class MolbioV2ResultData( data class MolbioV2ResultData(
val age: Int? = 0, val age: Int? = 0,
val analysisDate: String? = "", val analysisDate: String? = "2024-02-08 16:33:56",
val analysisStatus: String? = "", val analysisStatus: String? = "",
val analysisType: String? = "", val analysisType: String? = "",
val analysisTypeMethod: String? = "", val analysisTypeMethod: String? = "",
val bloodGroup: String? = "", val bloodGroup: String? = "",
val coefficients: List<Int>? = listOf(), val coefficients: List<Int>? = listOf(),
val collectionLocation: List<Any>? = listOf(), val collectionLocation: List<Any>? = listOf(),
val collectionTime: String? = "", val collectionTime: String? = "2024-02-08 16:33:56",
val collector: String? = "", val collector: String? = "",
val createdAt: String? = "", val createdAt: String? = "",
val createdBy: Int? = 0, val createdBy: Int? = 0,
val curveFitting: String? = "", val curveFitting: String? = "",
val deviceId: Int? = 0, val deviceId: Int? = 0,
val expiryTime: String? = "", val expiryTime: String? = "2024-02-08 16:33:56",
val gender: String? = "", val gender: String? = "",
val id: Int? = 0, val id: Int? = 0,
val interpretation: String? = "", val interpretation: String? = "",
@@ -32,11 +32,11 @@ data class MolbioV2ResultData(
val testId: String? = "", val testId: String? = "",
val testResult: String? = "", val testResult: String? = "",
val testStatus: String? = "", val testStatus: String? = "",
val testTime: String? = "", val testTime: String? = "2024-02-08 16:33:56",
val testType: String? = "", val testType: String? = "",
val thresholds: String? = "", val thresholds: String? = "",
val underMedication: Boolean? = false, val underMedication: Boolean? = false,
val updatedAt: String? = "", val updatedAt: String? = "",
val updatedBy: Int? = 0, val updatedBy: Int? = 0,
val volume: Int? = 0 val volume: Int? = 0,
) )

View File

@@ -1,5 +1,5 @@
package com.example.hpostesting.data.model.molbioresult package com.example.hpostesting.data.model.molbioresult
data class MolbioV2ResultRequest( data class MolbioV2ResultRequest(
val results: MutableList<MolbioV2Result>? = mutableListOf() val results: MutableList<MolbioV2Result>? = mutableListOf(),
) )

View File

@@ -8,5 +8,5 @@ data class MolbioV2ResultResponse(
@SerializedName("Message") @SerializedName("Message")
val message: String? = "", val message: String? = "",
@SerializedName("Result") @SerializedName("Result")
val result: String? = "" val result: String? = "",
) )

View File

@@ -19,7 +19,7 @@ data class RawData(
var gender: String = "", var gender: String = "",
var localFlag: Boolean = false, var localFlag: Boolean = false,
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 kitSerial: String = "", var kitSerial: String = "",

View File

@@ -9,7 +9,7 @@ data class BufferCheckData(
var _id: String = "", 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 localFlag: Boolean = false,

View File

@@ -15,5 +15,25 @@ data class DeviceData(
@get:PropertyName("coefficients") @set:PropertyName("coefficients") @get:PropertyName("coefficients") @set:PropertyName("coefficients")
var coefficients: List<Double> = emptyList(), var coefficients: List<Double> = emptyList(),
@get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt") @get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt")
var calibratedAt: String = "" var calibratedAt: String = "",
@get:PropertyName("deviceProvisionResponse") @set:PropertyName("deviceProvisionResponse")
var deviceProvisionResponse: String = "",
@get:PropertyName("username") @set:PropertyName("username")
var username: String = "",
@get:PropertyName("password") @set:PropertyName("password")
var password: String = "",
@get:PropertyName("natsToken") @set:PropertyName("natsToken")
var natsToken: String = "",
@get:PropertyName("natsTokenExpiry") @set:PropertyName("natsTokenExpiry")
var natsTokenExpiry: String = "",
@get:PropertyName("deviceUpdateAvailable") @set:PropertyName("deviceUpdateAvailable")
var deviceUpdateAvailable: Boolean = false,
@get:PropertyName("updatePath") @set:PropertyName("updatePath")
var updatePath: String = "",
@get:PropertyName("deviceVersion") @set:PropertyName("deviceVersion")
var deviceVersion: String = "",
@get:PropertyName("globalUpdateDone") @set:PropertyName("globalUpdateDone")
var globalUpdateDone: Boolean = false,
@get:PropertyName("globalUpdateIgnore") @set:PropertyName("globalUpdateIgnore")
var globalUpdateIgnore: Boolean = false,
) )

View File

@@ -5,7 +5,8 @@ import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table") @Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData( data class HemoCubeTestData(
@PrimaryKey @PrimaryKey(autoGenerate = true)
var sampleid: Int = 0,
var _id: String = "", var _id: String = "",
var name: String = "", var name: String = "",
var incubationTime: String = "", var incubationTime: String = "",
@@ -22,7 +23,7 @@ data class HemoCubeTestData(
var gender: String = "", var gender: String = "",
var localFlag: Boolean = false, var localFlag: Boolean = false,
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 kitSerial: String = "", var kitSerial: String = "",
@@ -78,6 +79,7 @@ data class HemoCubeTestData(
var prdClassification: String = "", var prdClassification: String = "",
var deviceRatioClass: String = "", var deviceRatioClass: String = "",
var slopeRatioClass: String = "", var slopeRatioClass: String = "",
var borderlineMethod2Class: String = "",
var errorMessages: String = "", var errorMessages: String = "",
var batteryLevel: String = "", var batteryLevel: String = "",
var batteryCapacity: String = "", var batteryCapacity: String = "",
@@ -89,5 +91,5 @@ data class HemoCubeTestData(
var solution: String? = "", var solution: String? = "",
var concentration: String? = "", var concentration: String? = "",
var volume: String? = "", var volume: String? = "",
var isCSVCreated: Boolean = false var isCSVCreated: Boolean = false,
) )

View File

@@ -18,7 +18,7 @@ data class PatientDetails(
var address: Address?, var address: Address?,
var category: Category?, var category: Category?,
var registerDate: Date?, var registerDate: Date?,
var uploadDate: Date? var uploadDate: Date?,
) { ) {
constructor() : this( constructor() : this(
"", "",
@@ -45,7 +45,6 @@ data class PatientDetails(
OTHER OTHER
} }
data class Address( data class Address(
var house: String?, var house: String?,
val street: String?, val street: String?,

View File

@@ -29,7 +29,7 @@ data class UserData(
var reportPath: String = "", var reportPath: String = "",
var result: TestRightResultType? = null, var result: TestRightResultType? = null,
var resultRatio: Double? = null, var resultRatio: Double? = null,
var prdClassification: String = "" var prdClassification: String = "",
) { ) {
enum class Gender { enum class Gender {
MALE, MALE,
@@ -39,7 +39,7 @@ data class UserData(
data class Location( data class Location(
var latitude: Double? = null, var latitude: Double? = null,
var longitude: Double? = null var longitude: Double? = null,
) )
} }

View File

@@ -1,29 +0,0 @@
package com.example.hpostesting.di
import android.content.Context
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@Provides
fun provideTestRightViewModel(
saveRawData: SaveRawData,
saveRawDataTest: SaveRawDataTest,
databaseRepository: DatabaseRepository,
userDao: UserDao,
context: Context
): TestRightViewModel {
return TestRightViewModel(saveRawData, saveRawDataTest, databaseRepository, userDao, context)
}
}

View File

@@ -1,5 +1,5 @@
package com.example.hpostesting.data.model.updates package com.example.hpostesting.data.model.updates
data class CheckUpdateData( data class CheckUpdateData(
val version: String? = "" val version: String? = "",
) )

View File

@@ -1,5 +1,5 @@
package com.example.hpostesting.data.model.updates package com.example.hpostesting.data.model.updates
data class CheckUpdateRequest( data class CheckUpdateRequest(
val currentVersion: String? = "" val currentVersion: String? = "",
) )

View File

@@ -8,5 +8,5 @@ data class CheckUpdateResponse(
@SerializedName("Message") @SerializedName("Message")
val message: String? = "", val message: String? = "",
@SerializedName("Result") @SerializedName("Result")
val result: String? = "" val result: String? = "",
) )

View File

@@ -1,5 +1,5 @@
package com.example.hpostesting.data.model.updates package com.example.hpostesting.data.model.updates
data class DeviceUpdateRequest( data class DeviceUpdateRequest(
val serial_no: String? = "" val serial_no: String? = "",
) )

View File

@@ -1,14 +1,17 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.net.Uri import android.net.Uri
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.model.PendingUploads import com.example.hpostesting.data.model.PendingUploads
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.jig.JigData
import com.example.hpostesting.data.model.log.UploadLogsResponse import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.login.LoginResponse
@@ -37,8 +40,8 @@ import javax.inject.Named
class NetworkException(message: String, cause: Throwable) : Exception(message, cause) class NetworkException(message: String, cause: Throwable) : Exception(message, cause)
class DatabaseRepository @Inject constructor( class DatabaseRepository @Inject constructor(
@Named("Auth")private val molbioAuthApi: MolbioAuthApi, @Named("Auth") private val molbioAuthApi: MolbioAuthApi,
private val molbioResultApi: MolbioResultApi private val molbioResultApi: MolbioResultApi,
) : Repository { ) : Repository {
private val db: FirebaseFirestore = Firebase.firestore private val db: FirebaseFirestore = Firebase.firestore
@@ -77,6 +80,14 @@ class DatabaseRepository @Inject constructor(
return safeApiCall { molbioResultApi.deviceUpdate(deviceUpdateRequest) } return safeApiCall { molbioResultApi.deviceUpdate(deviceUpdateRequest) }
} }
override suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse> {
return safeApiCall { molbioResultApi.deviceDiagnostics(deviceDiagnosticsRequest) }
}
override suspend fun downloadClientCertificate(): Result<ResponseBody> {
return safeApiCall { molbioResultApi.downloadClientCertificate() }
}
override suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse> { override suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse> {
return safeApiCall { molbioResultApi.uploadLogs(logFile) } return safeApiCall { molbioResultApi.uploadLogs(logFile) }
} }
@@ -98,20 +109,7 @@ class DatabaseRepository @Inject constructor(
} }
override suspend fun addTestToDatabase(data: UserData?): Response<String> { override suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try { TODO("Not yet implemented")
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
} }
override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> { override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
@@ -134,8 +132,18 @@ class DatabaseRepository @Inject constructor(
} }
} }
override suspend fun addTestJigData(data: JigData?): Response<String> {
return try {
db.collection("jigs").add(data!!).await()
Response.Success(data.deviceId)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
override suspend fun uploadFileToStorage( override suspend fun uploadFileToStorage(
patientID: String, filePath: String patientID: String, filePath: String,
): Response<Boolean> { ): Response<Boolean> {
try { try {
@@ -203,7 +211,45 @@ class DatabaseRepository @Inject constructor(
return allDeviceDataList.find { it.deviceId == deviceId } return allDeviceDataList.find { it.deviceId == deviceId }
} }
override suspend fun getDeviceResponse(data: DeviceData?): Response<String> {
return try {
db.collection("devices").add(data!!).await()
Response.Success(data.deviceProvisionResponse)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
override suspend fun uploadDeviceId(data: DeviceData): Response<String>? {
return try {
db.collection("devices").add(data!!).await()
Response.Success(data.deviceId)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
override fun <UserData> addTestToDatabase(testDetails: UserData): Any { override fun <UserData> addTestToDatabase(testDetails: UserData): Any {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
} }

View File

@@ -1,10 +1,13 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.jig.JigData
import com.example.hpostesting.data.model.log.UploadLogsResponse import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.login.LoginResponse
@@ -22,6 +25,7 @@ import okhttp3.ResponseBody
interface Repository { interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String> suspend fun addTestToDatabase(data: UserData?): Response<String>
@@ -29,9 +33,13 @@ interface Repository {
suspend fun addDiagnostics(data: DiagnosticsData?): Response<String> suspend fun addDiagnostics(data: DiagnosticsData?): Response<String>
suspend fun addTestJigData(data: JigData?): Response<String>
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean>
suspend fun getDeviceDataById(deviceId: String): DeviceData? suspend fun getDeviceDataById(deviceId: String): DeviceData?
suspend fun getDeviceResponse(data: DeviceData?): Response<String>
suspend fun uploadDeviceId(data: DeviceData): Response<String>?
abstract fun <UserData> addTestToDatabase(testDetails: UserData): Any abstract fun <UserData> addTestToDatabase(testDetails: UserData): Any
// suspend fun addToDatabase(data: PatientDetails) // suspend fun addToDatabase(data: PatientDetails)
@@ -44,6 +52,7 @@ interface Repository {
suspend fun checkUpdate(checkUpdateRequest: CheckUpdateRequest): Result<CheckUpdateResponse> suspend fun checkUpdate(checkUpdateRequest: CheckUpdateRequest): Result<CheckUpdateResponse>
suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): Result<ResponseBody> suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): Result<ResponseBody>
suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse>
suspend fun downloadClientCertificate(): Result<ResponseBody>
suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse> suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse>
} }

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.domain.di package com.example.hpostesting.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
@@ -7,7 +7,7 @@ import android.content.res.AssetManager
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.api.PropertyProvider import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.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
@@ -22,6 +22,8 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProviderImpl import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
@@ -145,7 +147,7 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideRetrofit( fun provideRetrofit(
propertyProvider: PropertyProvider,@Named("Auth") client: OkHttpClient propertyProvider: PropertyProvider, @Named("Auth") client: OkHttpClient
): Retrofit { ): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client) return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build() .addConverterFactory(GsonConverterFactory.create()).build()
@@ -179,4 +181,10 @@ object AppModule {
fun provideLocalFileDataSource(): LocalFileDataSource { fun provideLocalFileDataSource(): LocalFileDataSource {
return LocalFileDataSourceImpl() return LocalFileDataSourceImpl()
} }
@Provides
@Singleton
fun provideUsbServiceListener(context: Context): UsbServiceListener {
return UsbServiceListenerImpl(context)
}
} }

View File

@@ -1,10 +1,10 @@
package com.example.hpostesting.domain package com.example.hpostesting.domain
import android.util.Log import android.util.Log
import com.example.hpostesting.data.repository.LocalFileRepository
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpostesting.data.repository.LocalFileRepository
import java.util.Collections.sort import java.util.Collections.sort
class SaveRawData(private val localFileRepository: LocalFileRepository) { class SaveRawData(private val localFileRepository: LocalFileRepository) {
@@ -98,7 +98,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
folderPath: String, folderPath: String,
fileName: String, fileName: String,
calculationData: TestRightCalculationData, calculationData: TestRightCalculationData,
testDetails: UserData? testDetails: UserData?,
) { ) {
// val fileObj = File(folderPath, fileName) // val fileObj = File(folderPath, fileName)
// val writer = FileWriter(fileObj) // val writer = FileWriter(fileObj)
@@ -116,7 +116,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
private fun getLogStringFromObjWithPatientData( private fun getLogStringFromObjWithPatientData(
calculationData: TestRightCalculationData, calculationData: TestRightCalculationData,
testDetails: UserData? testDetails: UserData?,
): String { ): String {
var outputString = "Test calculation logs ==>\n" var outputString = "Test calculation logs ==>\n"
outputString += "Name = ${testDetails?.name}\n" outputString += "Name = ${testDetails?.name}\n"

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.widget.EditText import android.widget.EditText
import android.widget.Toast 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.constant.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.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
@@ -87,7 +87,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
override fun dcssdkEventAuxScannerAppeared( override fun dcssdkEventAuxScannerAppeared(
dcsScannerInfo: DCSScannerInfo?, dcsScannerInfo: DCSScannerInfo?,
dcsScannerInfo1: DCSScannerInfo? dcsScannerInfo1: DCSScannerInfo?,
) { ) {
} }
@@ -119,7 +119,6 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
// } // }
// } // }
try { try {
if (checkHemoCubeKitData()) { if (checkHemoCubeKitData()) {
DataHolder.selectedTest!!.kitSerial = DataHolder.selectedTest!!.kitSerial =
@@ -156,7 +155,6 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
pullTrigger() pullTrigger()
} }
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)) {
@@ -223,24 +221,39 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
notifications_mask or DCSSDKDefs.DCSSDK_EVENT.DCSSDK_EVENT_BARCODE.value notifications_mask or DCSSDKDefs.DCSSDK_EVENT.DCSSDK_EVENT_BARCODE.value
sdkHandler!!.dcssdkSubsribeForEvents(notifications_mask) sdkHandler!!.dcssdkSubsribeForEvents(notifications_mask)
mScannerInfoList.addAll(sdkHandler!!.dcssdkGetAvailableScannersList()) mScannerInfoList.addAll(sdkHandler!!.dcssdkGetAvailableScannersList())
sdkHandler!!.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID) Log.e("scannersize", sdkHandler!!.dcssdkGetAvailableScannersList().size.toString())
if (mScannerInfoList.isNotEmpty()) {
sdkHandler!!.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID)
} else {
Toast.makeText(this,"Scanner Is not available In this device", Toast.LENGTH_LONG).show()
}
} }
fun pullTrigger() { private fun pullTrigger() {
if (!mScannerInfoList[0].isActive) { // Check if the list is not empty before accessing its elements
sdkHandler!!.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID) if (mScannerInfoList.isNotEmpty()) {
// Only proceed if the scanner is not active
if (!mScannerInfoList[0].isActive) {
sdkHandler?.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID)
}
val inXML = "<inArgs><scannerID> 1 </scannerID></inArgs>"
val outXML = StringBuilder()
val result: DCSSDK_RESULT =
sdkHandler!!.dcssdkExecuteCommandOpCodeInXMLForScanner(
DCSSDK_COMMAND_OPCODE.DCSSDK_DEVICE_PULL_TRIGGER,
inXML,
outXML,
mScannerInfoList[0].scannerID // Ensure you're using the correct scanner ID
)
if (result == DCSSDK_RESULT.DCSSDK_RESULT_SUCCESS) {
Log.d("Scanning", "Success")
} else if (result == DCSSDK_RESULT.DCSSDK_RESULT_FAILURE) {
Log.d("Scanning", "Failed")
}
} else {
// Handle the case where the list is empty, perhaps notify the user or log an error
Log.e("ScannerError", "No scanners are connected or available.")
} }
val inXML = "<inArgs><scannerID> 1 </scannerID></inArgs>"
val outXML = StringBuilder()
val result: DCSSDK_RESULT =
sdkHandler!!.dcssdkExecuteCommandOpCodeInXMLForScanner(
DCSSDK_COMMAND_OPCODE.DCSSDK_DEVICE_PULL_TRIGGER, inXML, outXML, 1
)
if (result == DCSSDK_RESULT.DCSSDK_RESULT_SUCCESS) Log.d(
"Scanning",
"Success"
) else if (result == DCSSDK_RESULT.DCSSDK_RESULT_FAILURE) Log.d("Scanning", "Failed")
//new MyAsyncTask(1, DCSSDKDefs.DCSSDK_COMMAND_OPCODE.DCSSDK_DEVICE_PULL_TRIGGER,null).execute(inXML);
} }
//this function is called if barcode is detected. //this function is called if barcode is detected.
@@ -257,7 +270,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
return sharedPreference.getString(Constants.KIT_NUMBER, "") return sharedPreference.getString(Constants.KIT_NUMBER, "")
?.isNotBlank() == true && sharedPreference.getInt( ?.isNotBlank() == true && sharedPreference.getInt(
Constants.KIT_COUNT, 0 Constants.KIT_COUNT, 0
) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35 ) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < Constants.KIT_CAPACITY
} }
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {

View File

@@ -17,7 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat 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.constant.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.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
@@ -111,7 +111,11 @@ class MainActivity : AppCompatActivity() {
val deviceType = when { val deviceType = when {
availableDrivers.isNotEmpty() -> { availableDrivers.isNotEmpty() -> {
val device = availableDrivers[0].device val device = availableDrivers[0].device
Toast.makeText(this, "Connected, productId: ${device.productId}, vendorId: ${device.vendorId}", Toast.LENGTH_SHORT).show() Toast.makeText(
this,
"Connected, productId: ${device.productId}, vendorId: ${device.vendorId}",
Toast.LENGTH_SHORT
).show()
when { when {
device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID -> { device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE binding.cvItem1.visibility = View.VISIBLE
@@ -149,6 +153,15 @@ class MainActivity : AppCompatActivity() {
Constants.DEVICE_TYPE_HEMOCUBE Constants.DEVICE_TYPE_HEMOCUBE
} }
device.productId == 4614 && device.vendorId == 7111 -> {
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_HEMOCUBE)
Constants.DEVICE_TYPE_HEMOCUBE
}
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,
@@ -339,7 +352,7 @@ class MainActivity : AppCompatActivity() {
} }
override fun onRequestPermissionsResult( override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String>, grantResults: IntArray requestCode: Int, permissions: Array<String>, grantResults: IntArray,
) { ) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) { when (requestCode) {

View File

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

View File

@@ -1,134 +0,0 @@
package com.example.hpostesting.presentation
import android.util.Log
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import io.nats.client.AuthHandler
import io.nats.client.Connection
import io.nats.client.Message
import io.nats.client.NKey
import io.nats.client.Nats
import io.nats.client.Options
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.security.GeneralSecurityException
class NatsManager(datacollector: DashboardActivity) {
val TAG = "Nats Service"
var nc: Connection? = null
val datacollector = datacollector
var connect = false
fun connect() {
Log.d(TAG, "TRY TO CONNECT")
Thread {
val seedString = "SUAEB5PUWNS6C2HUV3MFI6HUDEAPGPFPBHMI73NHIQATCDD2BWALVEZXZ4"
val seedBytes = seedString.toCharArray()
val theNKey = NKey.fromSeed(seedBytes) // really should load from somewhere
val options = Options.Builder()
.server("nats://192.168.10.117:4222")
.authHandler(object : AuthHandler {
override fun getID(): CharArray? {
return try {
theNKey?.publicKey
} catch (ex: GeneralSecurityException) {
null
} catch (ex: IOException) {
null
} catch (ex: NullPointerException) {
null
}
}
override fun sign(nonce: ByteArray): ByteArray? {
return try {
theNKey?.sign(nonce)
} catch (ex: GeneralSecurityException) {
null
} catch (ex: IOException) {
null
} catch (ex: NullPointerException) {
null
}
}
override fun getJWT(): CharArray? {
return null
}
})
.build()
try {
nc = Nats.connect(options)
Log.d(TAG, "Connected to Nats server ${options.servers.first()}")
connect = true
datacollector.setConnect(true)
nc?.publish(
"server.hpos.HCV-000-3001.ping",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
)
nc?.publish(
"server.hpos.HCV-000-3001.health",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
)
Log.d(TAG, "Published msg server.hpos.HCV-000-3001.ping on topic Testing")
val d = nc?.createDispatcher { msg: Message? ->
println("PRITIMOI SARKAR $msg")
}
d?.subscribe("device.hpos.HCV-000-3001.update") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector. setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.uploadlogs") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response + "uPLOAD")
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.disable") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.updatecustomer") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.checkupdate") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
} catch (exp: Exception) {
println(exp.printStackTrace())
connect = false
datacollector.setConnect(true)
}
}.start()
}
fun pub(topic: String, msg: String) {
nc?.publish(topic, msg.toByteArray(StandardCharsets.UTF_8))
Log.d(TAG, "Published msg ${msg} on topic ${topic}")
}
fun close() {
nc?.close()
Log.d(TAG, "Nats connection close")
}
}

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.Manifest import android.Manifest
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -14,8 +13,9 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi 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.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity
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
@@ -53,7 +53,10 @@ class SplashActivity : AppCompatActivity() {
private fun setupStaticConstants() { private fun setupStaticConstants() {
DataHolder.mobileUniqueId = DataHolder.mobileUniqueId =
Settings.Secure.getString(applicationContext.contentResolver, Settings.Secure.ANDROID_ID) Settings.Secure.getString(
applicationContext.contentResolver,
Settings.Secure.ANDROID_ID
)
} }
// private fun setupFirestoreCache() { // private fun setupFirestoreCache() {
@@ -98,7 +101,10 @@ class SplashActivity : AppCompatActivity() {
private fun requestPermissionsBelowAndroidR() { private fun requestPermissionsBelowAndroidR() {
val permissionsToRequest = requiredPermissions val permissionsToRequest = requiredPermissions
.filterNot { permission -> .filterNot { permission ->
ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED ContextCompat.checkSelfPermission(
this,
permission
) == PackageManager.PERMISSION_GRANTED
} }
.toTypedArray() .toTypedArray()
@@ -114,9 +120,18 @@ class SplashActivity : AppCompatActivity() {
val coarseLocationPermission = Manifest.permission.ACCESS_COARSE_LOCATION val coarseLocationPermission = Manifest.permission.ACCESS_COARSE_LOCATION
val cameraPermission = Manifest.permission.CAMERA val cameraPermission = Manifest.permission.CAMERA
val locationPermissionsGranted = val locationPermissionsGranted =
ContextCompat.checkSelfPermission(this, fineLocationPermission) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
ContextCompat.checkSelfPermission(this, coarseLocationPermission) == PackageManager.PERMISSION_GRANTED this,
val cameraPermissionGranted = ContextCompat.checkSelfPermission(this, cameraPermission) == PackageManager.PERMISSION_GRANTED fineLocationPermission
) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(
this,
coarseLocationPermission
) == PackageManager.PERMISSION_GRANTED
val cameraPermissionGranted = ContextCompat.checkSelfPermission(
this,
cameraPermission
) == PackageManager.PERMISSION_GRANTED
if (locationPermissionsGranted && cameraPermissionGranted) { if (locationPermissionsGranted && cameraPermissionGranted) {
handlePermissionsResult(true) handlePermissionsResult(true)

View File

@@ -1,6 +0,0 @@
package com.example.hpostesting.presentation
interface UsbServiceListener {
fun onUsbRead(data: ByteArray?)
fun onUsbError(e: Exception?)
}

View File

@@ -11,19 +11,17 @@ import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
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.UserData
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding
import org.apache.commons.collections4.MapUtils.getString
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
class OfflineUserListAdapter(private val view: View, private val batLevel: Int) : class OfflineUserListAdapter(private val view: View, private val batLevel: Int) :
RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() { RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() {
@@ -33,13 +31,13 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
private val differCallback = object : DiffUtil.ItemCallback<HemoCubeTestData>() { private val differCallback = object : DiffUtil.ItemCallback<HemoCubeTestData>() {
override fun areItemsTheSame( override fun areItemsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData oldItem: HemoCubeTestData, newItem: HemoCubeTestData,
): Boolean { ): Boolean {
return oldItem._id == newItem._id return oldItem._id == newItem._id
} }
override fun areContentsTheSame( override fun areContentsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData oldItem: HemoCubeTestData, newItem: HemoCubeTestData,
): Boolean { ): Boolean {
return oldItem == newItem return oldItem == newItem
} }
@@ -104,20 +102,20 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
).show() ).show()
} else } else
if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) { if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) {
Toast.makeText( Toast.makeText(
view.context, view.context,
view.context.getString(R.string.incubation_crossed_30_minutes), view.context.getString(R.string.incubation_crossed_30_minutes),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} else { } else {
DataHolder.selectedTest = UserData( DataHolder.selectedTest = UserData(
_id = userList._id, _id = userList._id,
bloodGroup = userList.bloodGroup, bloodGroup = userList.bloodGroup,
incubationTime = userList.incubationTime incubationTime = userList.incubationTime
) )
view.findNavController() view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity) .navigate(R.id.action_nav_home_to_mainActivity)
} }
} else { } else {
Toast.makeText( Toast.makeText(
view.context, view.context,
@@ -143,7 +141,6 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
return diffMillis / (60 * 1000) return diffMillis / (60 * 1000)
} }
private fun showWarningToast(resId: Int) { private fun showWarningToast(resId: Int) {
val contextToUse = view.context ?: return val contextToUse = view.context ?: return

View File

@@ -4,30 +4,28 @@ import android.annotation.SuppressLint
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE import android.content.Context.INPUT_METHOD_SERVICE
import android.view.inputmethod.InputMethodManager
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.AutoCompleteTextView
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.FirebaseFirestore
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import android.widget.AutoCompleteTextView
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.firestore.FirebaseFirestore
class UserListAdapter( class UserListAdapter(
@@ -36,7 +34,7 @@ class UserListAdapter(
options: FirestoreRecyclerOptions<UserData>, options: FirestoreRecyclerOptions<UserData>,
private val view: View, private val view: View,
private val batLevel: Int, private val batLevel: Int,
private val requireActivity: FragmentActivity private val requireActivity: FragmentActivity,
) : FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) { ) : FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) : class OrderItemViewHolder(val binding: UserItemViewBinding) :
@@ -96,16 +94,21 @@ class UserListAdapter(
.setView(dialogView) .setView(dialogView)
.setTitle(R.string.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(R.string.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.equals("ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ") || 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)
} }
if (view != null) { if (view != null) {
Toast.makeText(context, view.context.getString(R.string.blood_group_toast), Toast.LENGTH_SHORT).show() Toast.makeText(
context,
view.context.getString(R.string.blood_group_toast),
Toast.LENGTH_SHORT
).show()
} }
} else { } else {
// Check if hemoCubeViewModel and testDetails are not null // Check if hemoCubeViewModel and testDetails are not null
@@ -119,7 +122,8 @@ class UserListAdapter(
val document = userdata.documents[0] val document = userdata.documents[0]
db.collection("patientData") db.collection("patientData")
.document(document.id) .document(document.id)
.update("bloodGroup", bloodGroup, .update(
"bloodGroup", bloodGroup,
"incubationTime", SimpleDateFormat( "incubationTime", SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time).toString() ).format(Calendar.getInstance().time).toString()

View File

@@ -8,7 +8,7 @@ import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.databinding.ActivityAssuranceControlsBinding import `in`.sminnovations.hpostesting.databinding.ActivityAssuranceControlsBinding
@AndroidEntryPoint @AndroidEntryPoint
class AssuranceControlsActivity: AppCompatActivity() { class AssuranceControlsActivity : AppCompatActivity() {
lateinit var binding: ActivityAssuranceControlsBinding lateinit var binding: ActivityAssuranceControlsBinding
lateinit var sharedPreference: SharedPreferences lateinit var sharedPreference: SharedPreferences

View File

@@ -12,15 +12,16 @@ import android.view.ViewGroup
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Spinner import android.widget.Spinner
import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import `in`.sminnovations.hpostesting.databinding.FragmentAssuranceControlsBinding import `in`.sminnovations.hpostesting.databinding.FragmentAssuranceControlsBinding
import java.time.Instant import java.time.Instant
class AssuranceControlsFragment: Fragment() { class AssuranceControlsFragment : Fragment() {
lateinit var binding: FragmentAssuranceControlsBinding lateinit var binding: FragmentAssuranceControlsBinding
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
@@ -30,6 +31,9 @@ class AssuranceControlsFragment: Fragment() {
binding = FragmentAssuranceControlsBinding.inflate(inflater, container, false) binding = FragmentAssuranceControlsBinding.inflate(inflater, container, false)
sharedPreferences = sharedPreferences =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
DataHolder.hemoCubeTestData!!.solution = ""
DataHolder.hemoCubeTestData!!.volume = ""
return binding.root return binding.root
} }
@@ -42,8 +46,9 @@ class AssuranceControlsFragment: Fragment() {
// binding.btnSubmit.visibility = View.GONE // binding.btnSubmit.visibility = View.GONE
val solutionSpinner: Spinner = binding.spinnerSolutions val solutionSpinner: Spinner = binding.spinnerSolutions
val solutionOptions = arrayOf("Select solution", "Tartrazine", "AR") val solutionOptions = arrayOf("Select solution", "Tartrazine", "Acid Red")
val solutionAdapter = ArrayAdapter(requireContext(), R.layout.simple_spinner_item, solutionOptions) val solutionAdapter =
ArrayAdapter(requireContext(), R.layout.simple_spinner_item, solutionOptions)
solutionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) solutionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
solutionSpinner.adapter = solutionAdapter solutionSpinner.adapter = solutionAdapter
solutionSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { solutionSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
@@ -51,7 +56,7 @@ class AssuranceControlsFragment: Fragment() {
parent: AdapterView<*>?, parent: AdapterView<*>?,
view: View?, view: View?,
position: Int, position: Int,
id: Long id: Long,
) { ) {
val selectedValue: String = solutionOptions[position] val selectedValue: String = solutionOptions[position]
if (!selectedValue.equals("Select solution")) { if (!selectedValue.equals("Select solution")) {
@@ -64,8 +69,21 @@ class AssuranceControlsFragment: Fragment() {
} }
val concentrationSpinner: Spinner = binding.spinnerConcentration val concentrationSpinner: Spinner = binding.spinnerConcentration
val concentrationOptions = arrayOf("Select concentration", "65umol", "45umol", "22.5umol", "12.25umol", "6.125umol", "75umol", "50umol", "25umol", "12.5umol", "6.25umol") val concentrationOptions = arrayOf(
val concentrationAdapter = ArrayAdapter(requireContext(), R.layout.simple_spinner_item, concentrationOptions) "Select concentration",
"65umol",
"45umol",
"22.5umol",
"12.25umol",
"6.125umol",
"75umol",
"50umol",
"25umol",
"12.5umol",
"6.25umol"
)
val concentrationAdapter =
ArrayAdapter(requireContext(), R.layout.simple_spinner_item, concentrationOptions)
concentrationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) concentrationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
concentrationSpinner.adapter = concentrationAdapter concentrationSpinner.adapter = concentrationAdapter
concentrationSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { concentrationSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
@@ -73,7 +91,7 @@ class AssuranceControlsFragment: Fragment() {
parent: AdapterView<*>?, parent: AdapterView<*>?,
view: View?, view: View?,
position: Int, position: Int,
id: Long id: Long,
) { ) {
val selectedValue: String = concentrationOptions[position] val selectedValue: String = concentrationOptions[position]
if (!selectedValue.equals("Select concentration")) { if (!selectedValue.equals("Select concentration")) {
@@ -87,7 +105,8 @@ class AssuranceControlsFragment: Fragment() {
val volumeSpinner: Spinner = binding.spinnerVolume val volumeSpinner: Spinner = binding.spinnerVolume
val volumeOptions = arrayOf("Select volume", "1uml", "2uml", "4uml", "4.5uml", "5uml") val volumeOptions = arrayOf("Select volume", "1uml", "2uml", "4uml", "4.5uml", "5uml")
val volumeAdapter = ArrayAdapter(requireContext(), R.layout.simple_spinner_item, volumeOptions) val volumeAdapter =
ArrayAdapter(requireContext(), R.layout.simple_spinner_item, volumeOptions)
volumeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) volumeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
volumeSpinner.adapter = volumeAdapter volumeSpinner.adapter = volumeAdapter
volumeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { volumeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
@@ -95,12 +114,9 @@ class AssuranceControlsFragment: Fragment() {
parent: AdapterView<*>?, parent: AdapterView<*>?,
view: View?, view: View?,
position: Int, position: Int,
id: Long id: Long,
) { ) {
val selectedValue: String = volumeOptions[position] val selectedValue: String = volumeOptions[position]
if (!selectedValue.equals("Select volume")) {
DataHolder.hemoCubeTestData!!.volume = selectedValue
}
} }
override fun onNothingSelected(parent: AdapterView<*>?) { override fun onNothingSelected(parent: AdapterView<*>?) {
@@ -108,12 +124,15 @@ class AssuranceControlsFragment: Fragment() {
} }
// load saved values // load saved values
val savedSolution = sharedPreferences.getString(Constants.QUICK_CAPTURE_SOLUTION, "").toString() val savedSolution =
sharedPreferences.getString(Constants.QUICK_CAPTURE_SOLUTION, "").toString()
val solutionPosition = getPositionOfValue(savedSolution, solutionOptions.toList()) val solutionPosition = getPositionOfValue(savedSolution, solutionOptions.toList())
solutionSpinner.setSelection(solutionPosition) solutionSpinner.setSelection(solutionPosition)
val savedConcentration = sharedPreferences.getString(Constants.QUICK_CAPTURE_CONCENTRATION, "").toString() val savedConcentration =
val concentrationPosition = getPositionOfValue(savedConcentration, concentrationOptions.toList()) sharedPreferences.getString(Constants.QUICK_CAPTURE_CONCENTRATION, "").toString()
val concentrationPosition =
getPositionOfValue(savedConcentration, concentrationOptions.toList())
concentrationSpinner.setSelection(concentrationPosition) concentrationSpinner.setSelection(concentrationPosition)
val savedVolume = sharedPreferences.getString(Constants.QUICK_CAPTURE_VOLUME, "").toString() val savedVolume = sharedPreferences.getString(Constants.QUICK_CAPTURE_VOLUME, "").toString()
@@ -121,6 +140,19 @@ class AssuranceControlsFragment: Fragment() {
volumeSpinner.setSelection(volumePosition) volumeSpinner.setSelection(volumePosition)
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
val selectedSolution = binding.spinnerSolutions.selectedItem.toString()
val selectedConcentration = binding.spinnerConcentration.selectedItem.toString()
// Check if any of the selections are default values
if (selectedSolution == "Select solution") {
Toast.makeText(requireContext(), "Please select a solution", Toast.LENGTH_LONG).show()
return@setOnClickListener // Prevent further execution
}
if (selectedConcentration == "Select concentration") {
Toast.makeText(requireContext(), "Please select a concentration", Toast.LENGTH_LONG).show()
return@setOnClickListener // Prevent further execution
}
DataHolder.hemoCubeTestData!!.quickCapture = true DataHolder.hemoCubeTestData!!.quickCapture = true
val currentUnixTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val currentUnixTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Instant.now().epochSecond Instant.now().epochSecond
@@ -128,6 +160,8 @@ class AssuranceControlsFragment: Fragment() {
"" ""
} }
DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI" DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI"
DataHolder.hemoCubeTestData!!.solution = binding.spinnerSolutions.selectedItem.toString()
DataHolder.hemoCubeTestData!!.concentration = binding.spinnerConcentration.selectedItem.toString()
DataHolder.hemoCubeTestData!!.name = "${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}" DataHolder.hemoCubeTestData!!.name = "${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}"
DataHolder.selectedTest = UserData() DataHolder.selectedTest = UserData()
@@ -136,7 +170,10 @@ class AssuranceControlsFragment: Fragment() {
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.QUICK_CAPTURE_SOLUTION, DataHolder.hemoCubeTestData!!.solution) putString(Constants.QUICK_CAPTURE_SOLUTION, DataHolder.hemoCubeTestData!!.solution)
putString(Constants.QUICK_CAPTURE_CONCENTRATION, DataHolder.hemoCubeTestData!!.concentration) putString(
Constants.QUICK_CAPTURE_CONCENTRATION,
DataHolder.hemoCubeTestData!!.concentration
)
putString(Constants.QUICK_CAPTURE_VOLUME, DataHolder.hemoCubeTestData!!.volume) putString(Constants.QUICK_CAPTURE_VOLUME, DataHolder.hemoCubeTestData!!.volume)
apply() apply()
} }

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
@@ -31,7 +31,7 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding
@AndroidEntryPoint @AndroidEntryPoint
class AutoDacActivity: AppCompatActivity() { class AutoDacActivity : AppCompatActivity() {
private lateinit var binding: ActivityAutoDacBinding private lateinit var binding: ActivityAutoDacBinding
val viewModel: AutoDacViewModel by viewModels() val viewModel: AutoDacViewModel by viewModels()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -58,11 +58,9 @@ class AutoDacActivity: AppCompatActivity() {
DataHolder.usbConnected.postValue(true) DataHolder.usbConnected.postValue(true)
} }
} }
} }
} }
private val connection = object : ServiceConnection { private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) { override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder val binder = service as UsbService.UsbServiceBinder
@@ -107,6 +105,7 @@ class AutoDacActivity: AppCompatActivity() {
} }
} }
} }
open fun connectUsb(permissionGranted: Boolean) { open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted") Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -126,7 +125,6 @@ class AutoDacActivity: AppCompatActivity() {
} }
} }
fun onErrorReported(msg: String) { fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed() if (!isFinishing) onBackPressed()
@@ -161,17 +159,16 @@ class AutoDacActivity: AppCompatActivity() {
manager.requestPermission(device, mPendingIntent) manager.requestPermission(device, mPendingIntent)
} }
fun setupService() { fun setupService() {
val intent = Intent(this, UsbService::class.java) val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE) bindService(intent, connection, Context.BIND_AUTO_CREATE)
} }
override fun onCreateOptionsMenu(menu: Menu?): Boolean { override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu) menuInflater.inflate(R.menu.my_menu, menu)
return true return true
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (viewModel.isServiceConnected) { if (viewModel.isServiceConnected) {

View File

@@ -14,7 +14,7 @@ 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.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding
@@ -22,7 +22,7 @@ import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
class AutoDacFragment: Fragment() { class AutoDacFragment : Fragment() {
private lateinit var binding: FragmentAutoDacBinding private lateinit var binding: FragmentAutoDacBinding
private val autoDacViewModel: AutoDacViewModel by activityViewModels() private val autoDacViewModel: AutoDacViewModel by activityViewModels()
@@ -47,7 +47,6 @@ class AutoDacFragment: Fragment() {
observeViewModel() observeViewModel()
} }
private fun initViews() { private fun initViews() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
listenToHemoCube() listenToHemoCube()
@@ -56,9 +55,12 @@ class AutoDacFragment: Fragment() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
runAutoDacCommand() runAutoDacCommand()
} }
binding.btnReadDac.setOnClickListener {
binding.btnReadDac.visibility = View.GONE
readCurrentDACValuesCommand()
}
} }
private fun observeViewModel() { private fun observeViewModel() {
autoDacViewModel.deviceData.observe(viewLifecycleOwner) { autoDacViewModel.deviceData.observe(viewLifecycleOwner) {
@@ -93,6 +95,7 @@ class AutoDacFragment: Fragment() {
binding.tvSubtitle4.text = stringData binding.tvSubtitle4.text = stringData
} }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false) autoDacViewModel.progressBar.postValue(false)
} }
@@ -105,9 +108,36 @@ class AutoDacFragment: Fragment() {
HemoCubeCommands.AUTO_DAC_COMMAND, HemoCubeCommands.AUTO_DAC_COMMAND,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
} }
override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun setAutoDacValuesCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun readCurrentDACValuesCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.READ_DAC_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false) autoDacViewModel.progressBar.postValue(false)
} }
@@ -133,10 +163,10 @@ class AutoDacFragment: Fragment() {
val slData = stringData.split(" ") val slData = stringData.split(" ")
if (slData.size > 1) { if (slData.size > 1) {
val hardwareId = slData[1].trim() val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) { // with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId) // putString(Constants.DEVICE_ID, hardwareId)
apply() // apply()
} // }
} }
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE
@@ -145,9 +175,24 @@ class AutoDacFragment: Fragment() {
} }
if (resultData.contains("#CC")) { if (resultData.contains("#CC")) {
setAutoDacValuesCommand()
autoDacViewModel.addAutoDacDataToDb( autoDacViewModel.addAutoDacDataToDb(
DiagnosticsData( DiagnosticsData(
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
.toString(),
devicePassword = sharedPreferences.getString(
Constants.DEVICE_PASSWORD_API,
""
).toString(),
deviceNatsToken = sharedPreferences.getString(
Constants.NATS_TOKEN,
""
).toString(),
accessToken = sharedPreferences.getString(
Constants.ACCESS_TOKEN,
""
).toString(),
deviceData = resultData, deviceData = resultData,
runTime = SimpleDateFormat( runTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
@@ -158,6 +203,10 @@ class AutoDacFragment: Fragment() {
binding.ivCheck.visibility = View.VISIBLE binding.ivCheck.visibility = View.VISIBLE
} }
} }
if (resultData.contains("#WC")) {
showToast("DAC Values saved to EPROM")
}
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
@@ -169,7 +218,6 @@ class AutoDacFragment: Fragment() {
} }
} }
fun parseData(inputData: List<String>): List<Pair<String, String>> { fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)") val pattern = Regex("([A-Z]+)\\s(\\d+)")
val parsedData = mutableListOf<Pair<String, String>>() val parsedData = mutableListOf<Pair<String, String>>()

View File

@@ -2,12 +2,9 @@ package com.example.hpostesting.presentation.autodac
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.NetworkStatusLiveData
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.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
@@ -18,10 +15,10 @@ import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class AutoDacViewModel @Inject constructor( class AutoDacViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao, private val hemoCubeDao: HemoCubeDao,
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)

View File

@@ -15,7 +15,7 @@ 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.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
@@ -142,6 +142,10 @@ class HemoCubeBufferCheckFragment : 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() {
@@ -175,6 +179,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
resultData += stringData resultData += stringData
hemoCubeViewModel.deviceMessages.postValue(resultData)
when { when {
stringData.contains("SN") -> { stringData.contains("SN") -> {
@@ -201,8 +206,9 @@ class HemoCubeBufferCheckFragment : Fragment() {
stringData.contains("#BC") -> { stringData.contains("#BC") -> {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.tvSubtitle4.text = "Buffer Completed" binding.tvSubtitle4.text = "Buffer Completed"
binding.btnSamplestart.visibility = View.VISIBLE // binding.btnSamplestart.visibility = View.VISIBLE
} }
fetchResult()
} }
stringData.contains("#SS") -> { stringData.contains("#SS") -> {
@@ -218,9 +224,9 @@ class HemoCubeBufferCheckFragment : Fragment() {
} }
resultData.contains("REND") -> { resultData.contains("REND") -> {
hemoCubeViewModel.messages.postValue( // hemoCubeViewModel.messages.postValue(
"Data collected \n" + " Processing data" // "Data collected \n" + " 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 = bufferIntensity.toDoubleOrNull()!! led1BufferForDevice = bufferIntensity.toDoubleOrNull()!!
@@ -242,7 +248,7 @@ class HemoCubeBufferCheckFragment : Fragment() {
private fun processResult() { private fun processResult() {
try { try {
hemoCubeViewModel.messages.postValue("processing result") // hemoCubeViewModel.messages.postValue("processing result")
val deviceLog = resultData val deviceLog = resultData
val pInfo = requireActivity().packageManager.getPackageInfo( val pInfo = requireActivity().packageManager.getPackageInfo(

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
@@ -61,6 +61,7 @@ open class HemocubeBufferCheckActivity : AppCompatActivity() {
} }
} }
private val connection = object : ServiceConnection { private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) { override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder val binder = service as UsbService.UsbServiceBinder
@@ -127,18 +128,19 @@ open class HemocubeBufferCheckActivity : AppCompatActivity() {
@SuppressLint("MutableImplicitPendingIntent") @SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { val mPendingIntent: PendingIntent =
PendingIntent.getBroadcast( if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE PendingIntent.getBroadcast(
) this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
} else { )
PendingIntent.getBroadcast( } else {
this, PendingIntent.getBroadcast(
0, this,
Intent(Constants.HEMOCUBE_USB_PERMISSION), 0,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE Intent(Constants.HEMOCUBE_USB_PERMISSION),
) PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
} )
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter) registerReceiver(broadcastReceiver, filter)
@@ -153,7 +155,8 @@ open class HemocubeBufferCheckActivity : AppCompatActivity() {
private fun moveToNext() { private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeBufferCheckFragment()) supportFragmentManager.beginTransaction()
.replace(binding.fghemocube.id, HemoCubeBufferCheckFragment())
.commit() .commit()
} }

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
@@ -31,7 +31,7 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityCalibrationBinding import `in`.sminnovations.hpostesting.databinding.ActivityCalibrationBinding
@AndroidEntryPoint @AndroidEntryPoint
class CalibrationActivity: AppCompatActivity() { class CalibrationActivity : AppCompatActivity() {
private lateinit var binding: ActivityCalibrationBinding private lateinit var binding: ActivityCalibrationBinding
val viewModel: CalibrationViewModel by viewModels() val viewModel: CalibrationViewModel by viewModels()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -107,6 +107,7 @@ class CalibrationActivity: AppCompatActivity() {
} }
} }
} }
open fun connectUsb(permissionGranted: Boolean) { open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted") Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -136,41 +137,42 @@ class CalibrationActivity: AppCompatActivity() {
private fun moveToNext() { private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fgCalibration.id, CalibrationFragment()) supportFragmentManager.beginTransaction()
.replace(binding.fgCalibration.id, CalibrationFragment())
.commit() .commit()
} }
@SuppressLint("MutableImplicitPendingIntent") @SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { val mPendingIntent: PendingIntent =
PendingIntent.getBroadcast( if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE PendingIntent.getBroadcast(
) this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
} else { )
PendingIntent.getBroadcast( } else {
this, PendingIntent.getBroadcast(
0, this,
Intent(Constants.HEMOCUBE_USB_PERMISSION), 0,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE Intent(Constants.HEMOCUBE_USB_PERMISSION),
) PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
} )
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter) registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent) manager.requestPermission(device, mPendingIntent)
} }
fun setupService() { fun setupService() {
val intent = Intent(this, UsbService::class.java) val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE) bindService(intent, connection, Context.BIND_AUTO_CREATE)
} }
override fun onCreateOptionsMenu(menu: Menu?): Boolean { override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu) menuInflater.inflate(R.menu.my_menu, menu)
return true return true
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (viewModel.isServiceConnected) { if (viewModel.isServiceConnected) {

View File

@@ -17,13 +17,13 @@ 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.calibration.CalibrationData import com.example.hpostesting.data.model.calibration.CalibrationData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
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.databinding.FragmentCalibrationBinding import `in`.sminnovations.hpostesting.databinding.FragmentCalibrationBinding
class CalibrationFragment: Fragment() { class CalibrationFragment : Fragment() {
private lateinit var binding: FragmentCalibrationBinding private lateinit var binding: FragmentCalibrationBinding
private val calibrationViewModel: CalibrationViewModel by activityViewModels() private val calibrationViewModel: CalibrationViewModel by activityViewModels()
@@ -50,7 +50,6 @@ class CalibrationFragment: Fragment() {
loadSavedCalibration() loadSavedCalibration()
} }
private fun initViews() { private fun initViews() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
listenToHemoCube() listenToHemoCube()
@@ -226,6 +225,7 @@ class CalibrationFragment: Fragment() {
binding.tvSubtitle4.text = stringData binding.tvSubtitle4.text = stringData
} }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
calibrationViewModel.progressBar.postValue(false) calibrationViewModel.progressBar.postValue(false)
} }

View File

@@ -2,21 +2,12 @@ package com.example.hpostesting.presentation.calibration
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.calibration.CalibrationData import com.example.hpostesting.data.model.calibration.CalibrationData
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
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 javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@@ -30,12 +21,8 @@ class CalibrationViewModel @Inject constructor(
private val sharedPreference: SharedPreferences = private val sharedPreference: SharedPreferences =
context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
// private val _networkStatusLiveData = NetworkStatusLiveData(context)
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
// val networkStatusLiveData: LiveData<Boolean>
// get() = _networkStatusLiveData
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
val savedCalibrationData = MutableLiveData<String>()
fun loadSavedCalibrationData(): CalibrationData { fun loadSavedCalibrationData(): CalibrationData {
val calibrationData = CalibrationData() val calibrationData = CalibrationData()

View File

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

View File

@@ -1,10 +1,12 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.app.DownloadManager import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
@@ -18,62 +20,97 @@ 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.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.NatsManager import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.NatsManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.jig.JigActivity
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
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import okhttp3.ResponseBody
import java.io.File import java.io.File
open interface IDataCollector { interface NatsMessageCallback {
fun onMessageReceived(topic: String, message: String)
}
open interface IDataCollector: NatsMessageCallback {
fun setConnect(connect: Boolean) fun setConnect(connect: Boolean)
fun setResponse(response: String) fun setResponse(response: String)
} }
@AndroidEntryPoint @AndroidEntryPoint
class DashboardActivity : AppCompatActivity(), IDataCollector { class DashboardActivity : AppCompatActivity(), IDataCollector {
val TAG = "DashboardActivity"
private var isRegistered = false
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
lateinit var sharedPreferences: SharedPreferences
var responses: String = "" var responses: String = ""
lateinit var nats: NatsManager lateinit var nats: NatsManager
private var downloadId: Long = 0 private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel // TODO: Remove hemocube viewmodel
private val hemocubeViewModel: HemoCubeViewModel by viewModels() private val hemocubeViewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences
override fun attachBaseContext(newBase: Context?) { override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!) val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode) LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase) super.attachBaseContext(newBase)
} }
override fun onMessageReceived(topic: String, message: String) {
// Handle incoming messages from NATS
Log.d(TAG, "Received message on topic $topic: $message")
}
@SuppressLint("SetWorldReadable")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDashboardBinding.inflate(layoutInflater) binding = ActivityDashboardBinding.inflate(layoutInflater)
sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar) setSupportActionBar(binding.appBarDashboard.toolbar)
nats = NatsManager(this) nats = NatsManager(this)
nats.connect() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.pub("server.hpos.HCV-000-3001.ping", "THIS IS A TEST MSG") nats.connect()
}
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]"
binding.appBarDashboard.versionName.text = versionName
val deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
nats.sub("server.hpos.${deviceId}.ping")
nats.pub("server.hpos.${deviceId}.ping", "THIS IS A TEST MSG")
hemocubeViewModel.deviceUpdate.observe(this) { result -> hemocubeViewModel.deviceUpdate.observe(this) { result ->
when (result) { when (result) {
is Result.Success -> { is Result.Success -> {
// Handle success // Handle success
val apkUrl = result.data val apk = result.data
// val apkUrl = "https://dl.dropboxusercontent.com/s/fi/1c3nn7t0co431hicl3hrt/app-debug.apk?rlkey=e4uf13ty1dpcked614vy1aaqp&dl=0" val file = File(getExternalFilesDir("Updates"), "update.apk")
initiateUpdate(apkUrl.toString()) file.setReadable(true, false) // Ensure the file is readable
Log.d("ApI", "APK URL: $apkUrl") apk.byteStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
Log.d("Responsebodyformat", "Responsebodyformat: ")
installApk(file)
Log.e("ApI", "APK URL: $apk")
Toast.makeText( Toast.makeText(
this, this,
"APK UPLOAD ${result.data}", "${result.data}",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
@@ -100,13 +137,20 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
appBarConfiguration = AppBarConfiguration( appBarConfiguration = AppBarConfiguration(
setOf( setOf(
R.id.nav_home, R.id.nav_profile, R.id.nav_settings R.id.nav_home, R.id.nav_profile, R.id.nav_activity,R.id.nav_settings
), drawerLayout ), drawerLayout
) )
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController) navView.setupWithNavController(navController)
if (Constants.NAVIGATE_TO_TEST_JIG_DIRECTLY) {
startActivity(Intent(this, JigActivity::class.java))
finish()
}
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present. // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.dashboard, menu) menuInflater.inflate(R.menu.dashboard, menu)
@@ -118,51 +162,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
} }
private fun initiateUpdate(responseBody: String) {
val apkUrl = responseBody
if (!isValidHttpUrl(apkUrl)) {
return
}
val request = DownloadManager.Request(Uri.parse(apkUrl))
request.setTitle("App Update")
request.setDescription("Downloading update...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(this, "Updates", "update.apk")
val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
// val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
// registerReceiver(downloadReceiver, filter)
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
}
private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://")
}
private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId) {
installApk()
}
}
}
private fun installApk() {
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
private fun installApk(file: File) {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile( val uri: Uri = FileProvider.getUriForFile(
this, this,
"com.example.hpostesting.fileprovider", "${BuildConfig.APPLICATION_ID}.fileprovider",
file file
) )
// Create an intent to install the APK
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE) val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri installIntent.data = uri
installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
@@ -178,8 +186,14 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
override fun onDestroy() { override fun onDestroy() {
if(isRegistered) {
try {
// unregisterReceiver(downloadReceiver)
} catch (e: Exception) {
Log.d("HomeFragment", e.toString())
}
}
super.onDestroy() super.onDestroy()
// unregisterReceiver(downloadReceiver)
} }
override fun onResume() { override fun onResume() {
@@ -229,8 +243,32 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
override fun setResponse(response: String) { override fun setResponse(response: String) {
responses = responses+response+"\n" responses = responses+response+"\n"
println(responses) println(responses)
// if (response.contains("checkUpdate")) {
// hemocubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
// }
}
private fun createDeviceUpdateRequestData(): DeviceUpdateRequest {
return DeviceUpdateRequest(
serial_no = sharedPreference.getString(Constants.DEVICE_ID, "")
)
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
private fun getAppEnvironment(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.packageName.substringAfterLast('.')
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
} }
} }

View File

@@ -1,6 +1,7 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
@@ -14,17 +15,19 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.autodac.AutoDacActivity import com.example.hpostesting.presentation.autodac.AutoDacActivity
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
import com.example.hpostesting.presentation.calibration.CalibrationActivity import com.example.hpostesting.presentation.calibration.CalibrationActivity
import com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity
import com.example.hpostesting.presentation.deviceinfo.DeviceActivity import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
import com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
class GalleryFragment : Fragment() { class GalleryFragment : Fragment() {
private var _binding: FragmentGalleryBinding? = null private var _binding: FragmentGalleryBinding? = null
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private var userid = "" private var userid = ""
// This property is only valid between onCreateView and // This property is only valid between onCreateView and
// onDestroyView. // onDestroyView.
private val binding get() = _binding!! private val binding get() = _binding!!
@@ -35,7 +38,7 @@ class GalleryFragment : Fragment() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View { ): View {
// val galleryViewModel = // val galleryViewModel =
// ViewModelProvider(this).get(GalleryViewModel::class.java) // ViewModelProvider(this).get(GalleryViewModel::class.java)
@@ -55,7 +58,7 @@ class GalleryFragment : Fragment() {
) { ) {
binding.btnDeviceProvision.visibility = View.VISIBLE binding.btnDeviceProvision.visibility = View.VISIBLE
} else { } else {
binding.btnDeviceProvision.visibility = View.GONE binding.btnDeviceProvision.visibility = View.VISIBLE
} }
binding.btnDeviceProvision.setOnClickListener { binding.btnDeviceProvision.setOnClickListener {
@@ -82,6 +85,19 @@ class GalleryFragment : Fragment() {
startActivity(Intent(requireContext(), DeviceActivity::class.java)) startActivity(Intent(requireContext(), DeviceActivity::class.java))
} }
binding.btnFirefox.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.component = ComponentName("org.mozilla.firefox", "org.mozilla.gecko.BrowserApp")
startActivity(intent)
}
binding.btnFiles.setOnClickListener {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "file/*"
startActivity(intent)
}
userid = sharedPreferences.getString(Constants.USER_ID, "").toString() userid = sharedPreferences.getString(Constants.USER_ID, "").toString()
binding.tvSubtitle4.text = "Login ID : ${userid}" binding.tvSubtitle4.text = "Login ID : ${userid}"

View File

@@ -37,7 +37,8 @@ class SlideshowFragment : PreferenceFragmentCompat() {
// App Version Preference // App Version Preference
val appVersionPreference = Preference(requireContext()) val appVersionPreference = Preference(requireContext())
appVersionPreference.title = "App Version" appVersionPreference.title = "App Version"
appVersionPreference.summary = getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + " ]" appVersionPreference.summary =
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + " ]"
preferenceScreen.addPreference(languagePreference) preferenceScreen.addPreference(languagePreference)
preferenceScreen.addPreference(appVersionPreference) preferenceScreen.addPreference(appVersionPreference)

View File

@@ -3,11 +3,11 @@ package com.example.hpostesting.presentation.dashboard.ui
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
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.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
@@ -20,7 +20,7 @@ class LoginFragment : Fragment() {
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?,
): View { ): View {
_binding = FragmentLoginBinding.inflate(inflater, container, false) _binding = FragmentLoginBinding.inflate(inflater, container, false)
sharedPreference = sharedPreference =
@@ -33,7 +33,6 @@ class LoginFragment : Fragment() {
init() init()
} }
private fun init() { private fun init() {
if (isUserLoggedIn()) { if (isUserLoggedIn()) {
navigateToHomeFragment() navigateToHomeFragment()

View File

@@ -12,18 +12,21 @@ import android.content.SharedPreferences
import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
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
@@ -33,7 +36,7 @@ import `in`.sminnovations.hpostesting.databinding.ActivityDeviceBinding
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
@AndroidEntryPoint @AndroidEntryPoint
class DeviceActivity : AppCompatActivity() { class DeviceActivity : AppCompatActivity(), DeviceCommunicationHandler {
private lateinit var binding: ActivityDeviceBinding private lateinit var binding: ActivityDeviceBinding
private val deviceViewModel by viewModels<DeviceViewModel>() private val deviceViewModel by viewModels<DeviceViewModel>()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -169,6 +172,7 @@ class DeviceActivity : AppCompatActivity() {
menuInflater.inflate(R.menu.my_menu, menu) menuInflater.inflate(R.menu.my_menu, menu)
return true return true
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (deviceViewModel.isServiceConnected) { if (deviceViewModel.isServiceConnected) {
@@ -177,4 +181,11 @@ class DeviceActivity : AppCompatActivity() {
deviceViewModel.isServiceConnected = false deviceViewModel.isServiceConnected = false
} }
} }
override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) {
mService.sendAndListenToHemoCube(
command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
listener
)
}
} }

View File

@@ -12,14 +12,12 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
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.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
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.databinding.FragmentDeviceBinding import `in`.sminnovations.hpostesting.databinding.FragmentDeviceBinding
class DeviceFragment : Fragment() { class DeviceFragment : Fragment() {
private lateinit var binding: FragmentDeviceBinding private lateinit var binding: FragmentDeviceBinding
private val deviceViewModel: HemoCubeViewModel by activityViewModels() private val deviceViewModel: HemoCubeViewModel by activityViewModels()
@@ -61,6 +59,7 @@ class DeviceFragment : Fragment() {
binding.tvSubtitle4.text = "Device ID: ${stringData}" binding.tvSubtitle4.text = "Device ID: ${stringData}"
} }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
deviceViewModel.progressBar.postValue(false) deviceViewModel.progressBar.postValue(false)
} }
@@ -68,7 +67,6 @@ class DeviceFragment : Fragment() {
} }
private fun listenToHemoCube() { private fun listenToHemoCube() {
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()

View File

@@ -7,6 +7,7 @@ import com.example.hpostesting.data.model.patient.DeviceData
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 javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class DeviceViewModel @Inject constructor( class DeviceViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao, private val hemoCubeDao: HemoCubeDao,
@@ -15,11 +16,6 @@ class DeviceViewModel @Inject constructor(
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
val messages = MutableLiveData<String>() val messages = MutableLiveData<String>()
// private val _networkStatusLiveData = NetworkStatusLiveData(context)
// val allUserData = hemoCubeDao.getAll()
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
// val networkStatusLiveData: LiveData<Boolean>
// get() = _networkStatusLiveData
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
} }

View File

@@ -20,9 +20,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
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
@@ -31,7 +34,7 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding
@AndroidEntryPoint @AndroidEntryPoint
class DeviceProvisionActivity : AppCompatActivity() { class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler {
private lateinit var binding: ActivityAutoDacBinding private lateinit var binding: ActivityAutoDacBinding
val viewModel: DeviceProvisionViewModel by viewModels() val viewModel: DeviceProvisionViewModel by viewModels()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -142,18 +145,19 @@ class DeviceProvisionActivity : AppCompatActivity() {
@SuppressLint("MutableImplicitPendingIntent") @SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { val mPendingIntent: PendingIntent =
PendingIntent.getBroadcast( if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE PendingIntent.getBroadcast(
) this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
} else { )
PendingIntent.getBroadcast( } else {
this, PendingIntent.getBroadcast(
0, this,
Intent(Constants.HEMOCUBE_USB_PERMISSION), 0,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE Intent(Constants.HEMOCUBE_USB_PERMISSION),
) PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
} )
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter) registerReceiver(broadcastReceiver, filter)
@@ -180,4 +184,11 @@ class DeviceProvisionActivity : AppCompatActivity() {
viewModel.isServiceConnected = false viewModel.isServiceConnected = false
} }
} }
override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) {
mService.sendAndListenToHemoCube(
command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
listener
)
}
} }

View File

@@ -4,30 +4,36 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
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.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.Result import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.util.Result
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.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
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.databinding.FragmentDeviceProvisionBinding import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
class DeviceProvisionFragment : Fragment() { class DeviceProvisionFragment : Fragment() {
private var resultData: String = "" private var resultData: String = ""
private lateinit var binding: FragmentDeviceProvisionBinding private lateinit var binding: FragmentDeviceProvisionBinding
private val viewModel: DeviceProvisionViewModel by activityViewModels() private val viewModel: DeviceProvisionViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private lateinit var deviceProvisionResponse: String
private var currentDeviceData: DeviceData? = null
private var isOnline = false
val deviceData = MutableLiveData<DeviceData?>()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View { ): View {
binding = FragmentDeviceProvisionBinding.inflate(inflater, container, false) binding = FragmentDeviceProvisionBinding.inflate(inflater, container, false)
sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
@@ -44,18 +50,25 @@ class DeviceProvisionFragment : Fragment() {
listenToHemoCube() listenToHemoCube()
getDeviceId() getDeviceId()
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
viewModel.deviceProvision( if (Constants.MOLBIO_INTEGRATION) {
DeviceProvisionRequest( viewModel.deviceProvision(
email = Constants.deviceProvisionEmail, DeviceProvisionRequest(
password = Constants.deviceProvisionPassword, email = Constants.deviceProvisionEmail,
serialNumber = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), password = Constants.deviceProvisionPassword,
uid = sharedPreferences.getString(Constants.DEVICE_ID, "").toString() serialNumber = sharedPreferences.getString(Constants.DEVICE_ID, "")
.toString(),
uid = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()
)
) )
) }
} }
} }
private fun observeViewModel() { private fun observeViewModel() {
viewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response ->
when (response) { when (response) {
@@ -74,20 +87,49 @@ class DeviceProvisionFragment : Fragment() {
Constants.NATS_TOKEN, Constants.NATS_TOKEN,
response.data.data?.device?.deviceUser?.natsToken response.data.data?.device?.deviceUser?.natsToken
) )
response.data.data?.device?.deviceUser?.natsToken?.let {
Log.e(
"natstoken",
it
)
}
putString( putString(
Constants.NATS_TOKEN_EXPIRE_DATE, Constants.NATS_TOKEN_EXPIRE_DATE,
response.data.data?.device?.deviceUser?.natsTokenExpiry response.data.data?.device?.deviceUser?.natsTokenExpiry
) )
apply() apply()
} }
startActivity(Intent(requireContext(), DashboardActivity::class.java)) startActivity(
Intent(
requireContext(),
DashboardActivity::class.java
)
)
Toast.makeText( Toast.makeText(
activity, "Device registered successfully", Toast.LENGTH_LONG activity, "Device registered successfully", Toast.LENGTH_LONG
).show() ).show()
viewModel.addDeviceProvisionDataToDb(
DeviceData(
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
.toString(),
username = response.data.data?.credentials?.username.toString(),
password = response.data.data?.credentials?.password.toString(),
deviceProvisionResponse = response.data.data.toString(),
natsToken = response.data.data?.device?.deviceUser?.natsToken.toString(),
natsTokenExpiry = response.data.data?.device?.deviceUser?.natsTokenExpiry.toString(),
globalUpdateIgnore = false,
globalUpdateDone = false,
deviceUpdateAvailable = false
)
)
// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()))
Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString())
Log.e("idpass", deviceProvisionResponse)
} else { } else {
Toast.makeText( Toast.makeText(
activity, activity,
"An error occurred in device provision: ${response.data.message}", "An error in device provision: ${response.data.message}",
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE
@@ -112,9 +154,17 @@ class DeviceProvisionFragment : Fragment() {
else -> {} else -> {}
} }
} }
viewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
Toast.makeText(
activity,
"Device provision successfully uploaded to firebase",
Toast.LENGTH_LONG
).show()
}
}
} }
private fun getDeviceId() { private fun getDeviceId() {
(activity as DeviceProvisionActivity).mService.sendAndListenToHemoCube( (activity as DeviceProvisionActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
@@ -129,7 +179,8 @@ class DeviceProvisionFragment : Fragment() {
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
try { try {
(activity as DeviceProvisionActivity).mService.listenToHemoCube(object : UsbServiceListener { (activity as DeviceProvisionActivity).mService.listenToHemoCube(object :
UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
@@ -146,14 +197,19 @@ class DeviceProvisionFragment : Fragment() {
} }
} }
fun extractV2HardwareId(input: String): String? {
val pattern = Regex("SNS\\s*(.*?)\\s*SNE")
val matchResult: MatchResult? = pattern.find(input)
return matchResult?.groups?.get(1)?.value
}
private fun handleUsbData() { private fun handleUsbData() {
when { when {
resultData.contains("SNE") -> { resultData.contains("SNE") -> {
val pattern = Regex("HPP1-\\d{4}") val hardwareId = extractV2HardwareId(resultData)
val matchResult = pattern.find(resultData)
val hardwareId = matchResult?.value
if (hardwareId.toString().length == 9) { if (!hardwareId.isNullOrBlank()) {
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId) putString(Constants.DEVICE_ID, hardwareId)
apply() apply()

View File

@@ -3,9 +3,11 @@ package com.example.hpostesting.presentation.deviceprovision
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.patient.DeviceData
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
@@ -13,17 +15,54 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class DeviceProvisionViewModel @Inject constructor( class DeviceProvisionViewModel @Inject constructor(
private val databaseRepository: Repository private val repository: Repository,
) : ViewModel() { ) : ViewModel() {
var isServiceConnected = false var isServiceConnected = false
val deviceProvisionResponse = MutableLiveData<Result<DeviceProvisionResponse>>() val deviceProvisionResponse = MutableLiveData<Result<DeviceProvisionResponse>>()
val fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
val deviceData = MutableLiveData<DeviceData?>()
fun deviceProvision(deviceProvisionRequest: DeviceProvisionRequest) = viewModelScope.launch { fun deviceProvision(deviceProvisionRequest: DeviceProvisionRequest) = viewModelScope.launch {
deviceProvisionResponse.postValue(Result.Loading()) deviceProvisionResponse.postValue(Result.Loading())
databaseRepository.deviceProvision(deviceProvisionRequest).let { repository.deviceProvision(deviceProvisionRequest).let {
deviceProvisionResponse.postValue(it) deviceProvisionResponse.postValue(it)
} }
} }
fun addDeviceId(data: DeviceData) {
viewModelScope.launch {
try {
repository.uploadDeviceId(data)
fireBaseUpload.postValue("Successfully device Id uploaded to firebase")
} catch (e: Exception) {
// Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
fun addDeviceProvisionDataToDb(data: DeviceData) {
viewModelScope.launch {
try {
when (val response = repository.getDeviceResponse(data)) {
is Response.Success -> {
// Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Successfully device response uploaded to firebase")
}
is Response.Error -> {
// Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
}
else -> {}
}
} catch (e: Exception) {
// Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
} }

View File

@@ -11,16 +11,16 @@ import android.content.ServiceConnection
import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat 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.constant.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.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
@@ -63,7 +63,6 @@ class DiagnosticsActivity : AppCompatActivity() {
} }
} }
private val connection = object : ServiceConnection { private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) { override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder val binder = service as UsbService.UsbServiceBinder
@@ -108,6 +107,7 @@ class DiagnosticsActivity : AppCompatActivity() {
} }
} }
} }
open fun connectUsb(permissionGranted: Boolean) { open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted") Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -127,17 +127,16 @@ class DiagnosticsActivity : AppCompatActivity() {
} }
} }
fun onErrorReported(msg: String) { fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed() if (!isFinishing) onBackPressed()
} }
private fun moveToNext() { private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fgDiagnostics.id, DiagnosticsFragment()) supportFragmentManager.beginTransaction()
.replace(binding.fgDiagnostics.id, DiagnosticsFragment())
.commit() .commit()
} }
@@ -162,17 +161,16 @@ class DiagnosticsActivity : AppCompatActivity() {
manager.requestPermission(device, mPendingIntent) manager.requestPermission(device, mPendingIntent)
} }
fun setupService() { fun setupService() {
val intent = Intent(this, UsbService::class.java) val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE) bindService(intent, connection, Context.BIND_AUTO_CREATE)
} }
override fun onCreateOptionsMenu(menu: Menu?): Boolean { override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu) menuInflater.inflate(R.menu.my_menu, menu)
return true return true
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (viewModel.isServiceConnected) { if (viewModel.isServiceConnected) {

View File

@@ -1,6 +1,8 @@
package com.example.hpostesting.presentation.diagnostics package com.example.hpostesting.presentation.diagnostics
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
@@ -11,11 +13,15 @@ import android.widget.Toast
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.util.Result
import com.example.hpostesting.util.Result.Success
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.devicediagnostics.AdditionalDetails
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding
@@ -32,7 +38,10 @@ class DiagnosticsFragment : Fragment() {
private var resultData: String = "" private var resultData: String = ""
private val messages = MutableLiveData<String>() private val messages = MutableLiveData<String>()
private var startListening = MutableLiveData(false) private var startListening = MutableLiveData(false)
private val batteryStatus: Intent? =
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context?.registerReceiver(null, ifilter)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View { ): View {
@@ -56,7 +65,25 @@ class DiagnosticsFragment : Fragment() {
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
runDeviceDiagnostics() runDeviceDiagnostics()
val batteryLevel = "" //diagnosticsViewModel.getBatteryLevel().toString()
val batteryCapacity = "" //context?.let { diagnosticsViewModel.getBatteryCapacity(it).toString() }
val batteryMaxCapacity = "" //context?.let { diagnosticsViewModel.getBatteryMaxCapacity(it).toString() }
val batteryTemperature = "" //diagnosticsViewModel.getBatteryTemperature().toString()
val batteryVoltage = "" // context?.let { diagnosticsViewModel.getBatteryVoltage(it).toString() }
val additionalDetails = AdditionalDetails(
batteryLevel = batteryLevel,
batteryCapacity = batteryCapacity!!,
batteryMaxCapacity = batteryMaxCapacity!!,
batteryTemperature = batteryTemperature,
batteryVoltage = batteryVoltage!!
)
diagnosticsViewModel.deviceDiagnostics(
DeviceDiagnosticsRequest(additionalDetails = additionalDetails)
)
} }
} }
@@ -68,7 +95,7 @@ class DiagnosticsFragment : Fragment() {
messages.observe(viewLifecycleOwner) { messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it binding.tvSubtitle4.text = it
Log.e("diagnostics",binding.tvSubtitle4.text.toString()) Log.e("diagnostics", binding.tvSubtitle4.text.toString())
} }
diagnosticsViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> diagnosticsViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
@@ -81,6 +108,42 @@ class DiagnosticsFragment : Fragment() {
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
} }
diagnosticsViewModel.deviceDiagnosticsResponse.observe(viewLifecycleOwner) { response ->
when (response) {
is Success -> {
if (response.data.result == "Success") {
Toast.makeText(
activity, response.data.message ?: "Device diagnostics uploaded successfully", Toast.LENGTH_LONG
).show()
response.data.data?.let { diagnosticsData ->
val batteryLevel = diagnosticsData.additionalDetails?.batteryLevel
}
} else {
Toast.makeText(
activity,
"${response.data.message}",
Toast.LENGTH_LONG
).show()
}
}
is Result.Error -> {
// Handle the error scenario
Toast.makeText(
activity,
"An error occurred: ${response.exception.message}",
Toast.LENGTH_LONG
).show()
}
is Result.Loading -> {
}
}
}
} }
private fun getDeviceId() { private fun getDeviceId() {
@@ -95,6 +158,7 @@ class DiagnosticsFragment : Fragment() {
binding.tvSubtitle4.text = stringData binding.tvSubtitle4.text = stringData
} }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false) diagnosticsViewModel.progressBar.postValue(false)
} }
@@ -107,22 +171,23 @@ class DiagnosticsFragment : Fragment() {
HemoCubeCommands.DIAGNOSTICS_COMMAND, HemoCubeCommands.DIAGNOSTICS_COMMAND,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false) diagnosticsViewModel.progressBar.postValue(false)
} }
}) })
} }
private fun listenToHemoCube() { private fun listenToHemoCube() {
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
startListening.postValue(true) startListening.postValue(true)
try { try {
(activity as DiagnosticsActivity).mService.listenToHemoCube(object : UsbServiceListener { (activity as DiagnosticsActivity).mService.listenToHemoCube(object :
UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
@@ -146,13 +211,28 @@ class DiagnosticsFragment : Fragment() {
} }
if (resultData.contains("END") || fullReadOutput.contains("END")) { if (resultData.contains("END") || fullReadOutput.contains("END")) {
diagnosticsViewModel.addDiagnosticsDataToDb(DiagnosticsData( diagnosticsViewModel.addDiagnosticsDataToDb(
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), DiagnosticsData(
deviceData = resultData, deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
runTime = SimpleDateFormat( .toString(),
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() devicePassword = sharedPreferences.getString(
).format(Calendar.getInstance().time) Constants.DEVICE_PASSWORD_API,
)) ""
).toString(),
deviceNatsToken = sharedPreferences.getString(
Constants.NATS_TOKEN,
""
).toString(),
accessToken = sharedPreferences.getString(
Constants.ACCESS_TOKEN,
""
).toString(),
deviceData = resultData,
runTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
)
)
} }
// val inputData = mutableListOf<String>() // val inputData = mutableListOf<String>()
// while (true) { // while (true) {
@@ -175,7 +255,6 @@ class DiagnosticsFragment : Fragment() {
} }
} }
fun parseData(inputData: List<String>): List<Pair<String, String>> { fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)") val pattern = Regex("([A-Z]+)\\s(\\d+)")
val parsedData = mutableListOf<Pair<String, String>>() val parsedData = mutableListOf<Pair<String, String>>()

View File

@@ -3,16 +3,21 @@ package com.example.hpostesting.presentation.diagnostics
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
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
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class DiagnosticsViewModel @Inject constructor( class DiagnosticsViewModel @Inject constructor(
private val repository: Repository private val repository: Repository,
// context: Context,
) : ViewModel() { ) : ViewModel() {
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
@@ -20,7 +25,11 @@ class DiagnosticsViewModel @Inject constructor(
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
val deviceDiagnosticsResponse = MutableLiveData<Result<DeviceDiagnosticsResponse>>()
// private val batteryStatus: Intent? =
// IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
// context.registerReceiver(null, ifilter)
// }
fun addDiagnosticsDataToDb(data: DiagnosticsData) { fun addDiagnosticsDataToDb(data: DiagnosticsData) {
viewModelScope.launch { viewModelScope.launch {
try { try {
@@ -43,4 +52,81 @@ class DiagnosticsViewModel @Inject constructor(
} }
} }
} }
fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest) = viewModelScope.launch {
deviceDiagnosticsResponse.postValue(Result.Loading())
repository.deviceDiagnostics(deviceDiagnosticsRequest).let {
deviceDiagnosticsResponse.postValue(it)
}
}
// fun getBatteryLevel(): Float? {
// val batteryPct: Float? = batteryStatus?.let { intent ->
// val level: Int =
// intent.getIntExtra(
// BatteryManager.EXTRA_LEVEL,
// -1
// )
// val scale: Int =
// intent.getIntExtra(
// BatteryManager.EXTRA_SCALE,
// -1
// )
// level * 100 / scale.toFloat()
// }
//
// return batteryPct
// }
//
// fun getBatteryTemperature(): Float? {
// val batteryTemp: Float? = batteryStatus?.let { intent ->
// val temperature = intent.getIntExtra(
// BatteryManager.EXTRA_TEMPERATURE,
// 0
// )
// temperature.toFloat() / 10
// }
//
// return batteryTemp
// }
//
// fun getBatteryVoltage(context: Context): Float {
// val batteryIntent =
// context.registerReceiver(
// null,
// IntentFilter(Intent.ACTION_BATTERY_CHANGED)
// )
// val voltage = batteryIntent?.getIntExtra(
// BatteryManager.EXTRA_VOLTAGE,
// 0
// ) ?: 0
//
// // milli-volts to volts
// return voltage.toFloat() / 1000
// }
//
//
// fun getBatteryCapacity(context: Context): Int {
// val batteryManager =
// context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
// val currentCapacity =
// batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
//
// return currentCapacity
// }
//
// fun getBatteryMaxCapacity(context: Context): Float {
// val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
// val designCapacity =
// batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
// val currentCapacity =
// batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
//
// // Calculate the estimated maximum battery capacity in mAh
// val maxCapacity = currentCapacity.toFloat() / designCapacity.toFloat() * 100
//
// return maxCapacity
// }
} }

View File

@@ -1,25 +1,10 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import androidx.activity.viewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDigitalCardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDigitalCardBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
class DigitalCardActivity : AppCompatActivity() { class DigitalCardActivity : AppCompatActivity() {
@@ -38,10 +23,10 @@ class DigitalCardActivity : AppCompatActivity() {
moveToNext() moveToNext()
} }
private fun moveToNext() { private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, DigitalCardFragment()) supportFragmentManager.beginTransaction()
.replace(binding.fghemocube.id, DigitalCardFragment())
.commit() .commit()
} }
} }

View File

@@ -5,16 +5,14 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.fragment.app.Fragment
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 androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@@ -61,14 +59,16 @@ class DigitalCardFragment : Fragment() {
binding.State.text = "State: ${testDetails?.state}" binding.State.text = "State: ${testDetails?.state}"
binding.abhaid.text = "ABHA ID: ${testDetails?.abhaId}" binding.abhaid.text = "ABHA ID: ${testDetails?.abhaId}"
binding.blood.text = "Blood Group: ${testDetails?.bloodGroup}" binding.blood.text = "Blood Group: ${testDetails?.bloodGroup}"
binding.sicklecell.text = "Sickle-Cell: ${DataHolder.hemoCubeTestData?.prdClassification.toString()}" binding.sicklecell.text =
"Sickle-Cell: ${DataHolder.hemoCubeTestData?.prdClassification.toString()}"
} }
// Update the UI with the fetched details // Update the UI with the fetched details
val originalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) val originalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val originalDate: Date? = originalDateFormat.parse(SimpleDateFormat( val originalDate: Date? = originalDateFormat.parse(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() SimpleDateFormat(
).format(Calendar.getInstance().time)) "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
)
// Format the parsed date to "mm date, year" // Format the parsed date to "mm date, year"
val desiredDateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()) val desiredDateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault())

View File

@@ -1,9 +1,11 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -12,15 +14,15 @@ 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.DataHolder
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestState import com.example.hpostesting.data.model.TestState
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.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity 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
@@ -90,8 +92,11 @@ class HemoCubeFragment : Fragment() {
observeViewModel() observeViewModel()
} }
@SuppressLint("SetTextI18n")
private fun initViews() { private fun initViews() {
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
activity?.runOnUiThread { activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
@@ -106,8 +111,6 @@ class HemoCubeFragment : Fragment() {
binding.nameEditText.visibility = View.GONE binding.nameEditText.visibility = View.GONE
binding.tvTitle.visibility = View.GONE binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE binding.btnGo.visibility = View.GONE
// binding.btnSubmit.isEnabled = false
// binding.btnSubmit.isClickable = false
binding.btnPlacebuffer.visibility = View.GONE binding.btnPlacebuffer.visibility = View.GONE
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
@@ -134,7 +137,6 @@ class HemoCubeFragment : Fragment() {
checkAndStartProcess() checkAndStartProcess()
it.visibility = View.GONE it.visibility = View.GONE
} }
} }
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
@@ -148,32 +150,43 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") { if (result == "Success") {
uploadedToCloud = true uploadedToCloud = true
var accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString()
showToast(R.string.test_upload) showToast(R.string.test_upload)
hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { if (Constants.MOLBIO_INTEGRATION) {
when (it) { hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) {
is Result.Success -> { when (it) {
uploadedToMolbio = true is Result.Success -> {
if (Constants.MOLBIO_INTERGATION) { uploadedToMolbio = true
it.data.data?.get(0)?.rawData?.let { it1 -> it.data.data?.get(0)?.rawData?.let { it1 ->
hemoCubeViewModel.updateMolbioFlag( hemoCubeViewModel.updateMolbioFlag(
it1._id it1._id
) )
} }
handleReadingFinish()
hemoCubeViewModel.uploadLogs()
hemoCubeViewModel.downloadClientCertificate()
} }
handleReadingFinish()
}
is Result.Error -> {
binding.btnSubmit.visibility = View.VISIBLE
//Remove this line of code while deploying to IOCL
it.exception.let { message ->
Toast.makeText(activity, "An error occurred: $message", Toast.LENGTH_LONG)
.show()
}
handleReadingFinish()
}
else -> {} is Result.Error -> {
binding.btnSubmit.visibility = View.VISIBLE
//Remove this line of code while deploying to IOCL
it.exception.let { message ->
Toast.makeText(
activity,
"$message",
Toast.LENGTH_LONG
)
.show()
Log.d("resultuploadfail1", message.toString())
}
handleReadingFinish()
}
else -> {}
}
} }
} else {
handleReadingFinish()
} }
} }
if (result == "Local") { if (result == "Local") {
@@ -356,6 +369,20 @@ class HemoCubeFragment : Fragment() {
}) })
} }
private fun loadDACValues() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.LOAD_DAC_VALUES,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
fun handleUsbData(stringData: String) { fun handleUsbData(stringData: String) {
if (stringData.contains("#")) { if (stringData.contains("#")) {
isTestOngoing = true isTestOngoing = true
@@ -368,6 +395,7 @@ class HemoCubeFragment : Fragment() {
when { when {
resultData.contains("SNE") && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { resultData.contains("SNE") && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> {
processV2HardwareId(resultData) processV2HardwareId(resultData)
loadDACValues()
} }
(resultData.contains("SN") && !resultData.contains("SNS") && !resultData.contains("SNE") && resultData.length >= 15) && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> { (resultData.contains("SN") && !resultData.contains("SNS") && !resultData.contains("SNE") && resultData.length >= 15) && this.testStatusCode < TestStatus.CONFIG_COMPLETED.code -> {
@@ -387,6 +415,12 @@ class HemoCubeFragment : Fragment() {
fetchResult() fetchResult()
} }
(resultData.contains("#RC") && this.testStatusCode < TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code) -> {
this.testStatusCode = TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code
hemoCubeViewModel.messages.postValue("EPROM ADC Loaded")
showStartBufferButton()
}
resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> { resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started)) hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started))
this.testStatusCode = TestStatus.BUFFER_STARTED.code this.testStatusCode = TestStatus.BUFFER_STARTED.code
@@ -411,7 +445,8 @@ class HemoCubeFragment : Fragment() {
(resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> { (resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> {
this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code
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 = "" currentResultData = ""
} }
@@ -519,7 +554,8 @@ class HemoCubeFragment : Fragment() {
led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! led3Gain1 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain1 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! led4Gain1 =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
} }
sendSecondGainCommand() sendSecondGainCommand()
@@ -537,7 +573,8 @@ class HemoCubeFragment : Fragment() {
led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! led3Gain2 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain2 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! led4Gain2 =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
} }
sendForthGainCommand() sendForthGainCommand()
@@ -565,6 +602,7 @@ class HemoCubeFragment : Fragment() {
fun finishReading() { fun finishReading() {
repeatReadingCount += 1 repeatReadingCount += 1
isTestOngoing = false
if (readingsPerSample == 1) { if (readingsPerSample == 1) {
activity?.runOnUiThread { activity?.runOnUiThread {
@@ -633,23 +671,26 @@ class HemoCubeFragment : Fragment() {
if (!hardwareId.isNullOrBlank()) { if (!hardwareId.isNullOrBlank()) {
updateDeviceId(hardwareId) updateDeviceId(hardwareId)
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE
}
hemoCubeViewModel.messages.postValue(getString(R.string.start))
} else { } else {
hemoCubeViewModel.messages.postValue("Config error") hemoCubeViewModel.messages.postValue("Config error")
} }
if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) { if (!Constants.DEVICE_CONFIGURATION.containsKey(deviceHardwareId)) {
assignDefaultDevice(resultData) assignDefaultDevice(resultData)
testState.allErrorMessages += "Calibration configuration for this device id is not found\n" // testState.allErrorMessages += "Calibration configuration for this device id is not found\n"
} }
if (!Constants.BUFFER_INTENSITY_THRESHOLDS.containsKey(deviceHardwareId)) { if (!Constants.BUFFER_INTENSITY_THRESHOLDS.containsKey(deviceHardwareId)) {
testState.allErrorMessages += "ADC thresholds for this device id are not found\n" // testState.allErrorMessages += "ADC thresholds for this device id are not found\n"
} }
} }
fun showStartBufferButton() {
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE
}
hemoCubeViewModel.messages.postValue(getString(R.string.start))
}
fun extractV1HardwareId(input: String): String? { fun extractV1HardwareId(input: String): String? {
val regex = Regex("SN (\\S+)") val regex = Regex("SN (\\S+)")
val matchResult = regex.find(input) val matchResult = regex.find(input)
@@ -662,10 +703,10 @@ class HemoCubeFragment : Fragment() {
if (!hardwareId.isNullOrBlank()) { if (!hardwareId.isNullOrBlank()) {
updateDeviceId(hardwareId) updateDeviceId(hardwareId)
activity?.runOnUiThread { // activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE // binding.btnPlacebuffer.visibility = View.VISIBLE
} // }
hemoCubeViewModel.messages.postValue(getString(R.string.start)) // hemoCubeViewModel.messages.postValue(getString(R.string.start))
} else { } else {
hemoCubeViewModel.messages.postValue("Config error") hemoCubeViewModel.messages.postValue("Config error")
} }
@@ -682,10 +723,10 @@ class HemoCubeFragment : Fragment() {
fun assignDefaultDevice(configData: String) { fun assignDefaultDevice(configData: String) {
deviceHardwareId = "HCV-000-3001" deviceHardwareId = "HCV-000-3001"
testStatusCode = TestStatus.CONFIG_COMPLETED.code testStatusCode = TestStatus.CONFIG_COMPLETED.code
activity?.runOnUiThread { // activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE // binding.btnPlacebuffer.visibility = View.VISIBLE
} // }
hemoCubeViewModel.messages.postValue(getString(R.string.start)) // hemoCubeViewModel.messages.postValue(getString(R.string.start))
} }
fun extractV2HardwareId(input: String): String? { fun extractV2HardwareId(input: String): String? {
@@ -729,6 +770,7 @@ class HemoCubeFragment : Fragment() {
val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice)) val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice)) val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice))
val deviceRatio = led2Average / led1Average val deviceRatio = led2Average / led1Average
val borderlineMetric = (led1Average - led2Average) / deviceRatio
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!! ?.get(0)!!
@@ -743,9 +785,9 @@ class HemoCubeFragment : Fragment() {
)?.get(0)!! )?.get(0)!!
) { ) {
// validationError = true // validationError = true
testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)" // testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (low)"
activity?.runOnUiThread { activity?.runOnUiThread {
binding.errorMessage.text = getString(R.string.error_improper_buffer_low) // binding.errorMessage.text = getString(R.string.error_improper_buffer_low)
// binding.errorMessage.visibility = View.VISIBLE // binding.errorMessage.visibility = View.VISIBLE
} }
} }
@@ -763,11 +805,11 @@ class HemoCubeFragment : Fragment() {
)?.get(1)!! )?.get(1)!!
) { ) {
// validationError = true // validationError = true
testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n" // testState.allErrorMessages += "Error: Invalid Test. Improper buffer reading (high)" + "\n"
activity?.runOnUiThread { activity?.runOnUiThread {
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
} }
} }
@@ -805,15 +847,15 @@ class HemoCubeFragment : Fragment() {
calculatedPredictedDenovixRatio = fittedAbs3.div(fittedAbs1) calculatedPredictedDenovixRatio = fittedAbs3.div(fittedAbs1)
val slope = (led1Average - led2Average) / (435 - 415) val slope = (led4Average - led1Average) / (431 - 411)
val calculatedSlopeRatio = abs(led3Average / slope) val calculatedSlopeRatio = abs(led2Average / slope)
val slopeClass = slopeRatioClassification(calculatedSlopeRatio) val slopeClass = slopeRatioClassification(calculatedSlopeRatio)
if (fittedAbs1 <= fittedAbs2) { if (fittedAbs1 <= fittedAbs2) {
// validationError = true // validationError = true
testState.allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n" // testState.allErrorMessages += "Error: Invalid Test. Problem with de-oxygenation" + "\n"
activity?.runOnUiThread { activity?.runOnUiThread {
binding.errorMessage.text = getString(R.string.error_invalid_test) // binding.errorMessage.text = getString(R.string.error_invalid_test)
// binding.errorMessage.visibility = View.VISIBLE // binding.errorMessage.visibility = View.VISIBLE
} }
} }
@@ -826,7 +868,7 @@ class HemoCubeFragment : Fragment() {
} }
} }
var absorbanceLowerLimit = 0.0 val absorbanceLowerLimit = 0.0
if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) { if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) {
validationError = true validationError = true
activity?.runOnUiThread { activity?.runOnUiThread {
@@ -837,9 +879,9 @@ class HemoCubeFragment : Fragment() {
if (fittedAbs3 < 0.1) { if (fittedAbs3 < 0.1) {
// validationError = true // validationError = true
testState.allErrorMessages += "Error: Low Hb. Repeat test" + "\n" // testState.allErrorMessages += "Error: Low Hb. Repeat test" + "\n"
activity?.runOnUiThread { activity?.runOnUiThread {
binding.errorMessage.text = "Error: Low Hb. Repeat test" // binding.errorMessage.text = "Error: Low Hb. Repeat test"
// binding.errorMessage.visibility = View.VISIBLE // binding.errorMessage.visibility = View.VISIBLE
} }
} }
@@ -873,9 +915,20 @@ class HemoCubeFragment : Fragment() {
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
this.deviceRatioClass = deviceRatioClassification(deviceRatio) this.deviceRatioClass = deviceRatioClassification(deviceRatio)
this.borderlineMethod2Class = reclassifyWithBorderlineMethod2(deviceRatio, deviceRatioBorderlineThresholds(deviceRatio), led2Average)
this.slopeRatioClass = slopeClass this.slopeRatioClass = slopeClass
this.classificationResult = deviceRatioClass //findResult(calculatedRatio) this.classificationResult = findResultWithAdditionalMethods(
hemoCubeViewModel.messages.postValue("${this.deviceRatioClass} ${if (led4Average < 0.17) " - Low Hb" else ""}\n") deviceRatio,
deviceRatioClass,
borderlineMetric
)
hemoCubeViewModel.messages.postValue(
"${this.classificationResult} \n Device Ratio: ${
"%.3f".format(
this.deviceRatio
)
}"
)
if (DataHolder.hemoCubeTestData?.testType == "HB") if (DataHolder.hemoCubeTestData?.testType == "HB")
hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4") hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4")
this.errorMessages = testState.allErrorMessages this.errorMessages = testState.allErrorMessages
@@ -909,50 +962,97 @@ class HemoCubeFragment : Fragment() {
} }
} }
fun findResult(calculatedRatio: Double?): String { fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String {
try { try {
hemoCubeViewModel.messages.postValue("result classification") if (deviceRatio != null && led2Average != null) {
if (calculatedRatio != null) { if (deviceRatioClass == "Negative Borderline") {
if (calculatedRatio < 0.05) return if (led2Average >= 0.15)
return getString(R.string.error_repeat_test_higher_volume) "Borderline. Normal"
if (calculatedRatio in 0.05..0.155) { else
return getString(R.string.normal) "Borderline. Sickle Cell Trait"
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
return if (led2Average >= 0.19)
"Borderline. Sickle Cell Trait"
else
"Borderline. Sickle Cell Disease"
} }
if (calculatedRatio in 0.155..0.175)
return getString(R.string.negative_borderline)
if (calculatedRatio in 0.175..0.22)
return getString(R.string.sickle_cell_trait)
if (calculatedRatio in 0.22..0.25)
return getString(R.string.positive_for_sickle_cell)
if (calculatedRatio in 0.25..0.35)
return getString(R.string.sickle_cell_disease)
if (calculatedRatio > 0.35)
return getString(R.string.error_repeat_test_lower_volume)
} else {
return getString(R.string.invalid)
} }
} catch (e: Exception) { } catch (e: Exception) {
showToast(R.string.error_classification) handleException(e)
Firebase.crashlytics.recordException(e) return "Error"
return getString(R.string.error)
} }
return getString(R.string.invalid) return deviceRatioClass.toString()
}
fun findResultWithAdditionalMethods(
deviceRatio: Double?,
deviceRatioClass: String?,
borderlineMetric: Double?,
): String {
try {
// hemoCubeViewModel.messages.postValue("post classification checks")
if (deviceRatio != null && borderlineMetric != null) {
if (deviceRatioClass == "Negative Borderline") {
return if (borderlineMetric >= 2.4)
"Borderline. Normal"
else
"Borderline. Sickle Cell Trait"
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
return if (borderlineMetric >= 1.34)
"Borderline. Sickle Cell Trait"
else
"Borderline. Sickle Cell Disease"
}
}
} catch (e: Exception) {
handleException(e)
return "Error"
}
return deviceRatioClass.toString()
}
fun deviceRatioBorderlineThresholds(ratio: Double?): String {
try {
if (ratio != null) {
val roundedRatio = String.format("%.3f", ratio).toDouble()
if (roundedRatio >= 0.11 && roundedRatio < 0.237) {
// setSubtitleTextColor(R.color.green_2)
return "Normal"
}
if (roundedRatio in 0.237..0.242)
return "Negative Borderline"
if (roundedRatio in 0.242..0.318)
return "Sickle Cell Trait"
if (roundedRatio >= 0.318 && roundedRatio < 0.356)
return "Positive for Sickle Cell. HPLC for Confirmation"
if (roundedRatio in 0.356..0.7)
return "Sickle Cell Disease"
} else {
return "Invalid"
}
} catch (e: Exception) {
handleException(e)
return "Error"
}
return "Invalid"
} }
fun deviceRatioClassification(ratio: Double?): String { fun deviceRatioClassification(ratio: Double?): String {
try { try {
if (ratio != null) { if (ratio != null) {
if (ratio in 0.1..0.29) { if (ratio in 0.16..0.23) {
// setSubtitleTextColor(R.color.green_2) // setSubtitleTextColor(R.color.green_2)
return "Normal" return "Normal"
} }
if (ratio in 0.29..0.32) if (ratio in 0.23..0.25)
return "Negative Borderline, Repeat Test" return "Negative Borderline"
if (ratio in 0.32..0.35) if (ratio in 0.25..0.31)
return "Sickle Cell Trait" return "Sickle Cell Trait"
if (ratio in 0.35..0.38) if (ratio in 0.31..0.36)
return "Positive for Sickle Cell. HPLC for Confirmation" return "Positive for Sickle Cell. HPLC for Confirmation"
if (ratio in 0.38..0.5) if (ratio in 0.36..0.7)
return "Sickle Cell Disease" return "Sickle Cell Disease"
} else { } else {
return "Invalid" return "Invalid"

View File

@@ -12,10 +12,10 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.example.hpostesting.data.CsvWriter import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
@@ -79,6 +79,7 @@ class HemoCubeViewModel @Inject constructor(
val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>() val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>()
val deviceUpdate = MutableLiveData<Result<ResponseBody>>() val deviceUpdate = MutableLiveData<Result<ResponseBody>>()
val downloadcertificate = MutableLiveData<Result<ResponseBody>>()
val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>() val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>()
@@ -87,6 +88,8 @@ class HemoCubeViewModel @Inject constructor(
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll() val allUserData = hemoCubeDao.getAll()
val allLocalData = hemoCubeDao.getAll()
val allPendingUserToUpload = hemoCubeDao.getPendingUser()
val allKitTestData = hemoCubeBufferDao.getAll() val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
@@ -141,6 +144,14 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
fun uploadResultfornew(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
}
fun checkUpdate(checkUpdateRequest: CheckUpdateRequest) = viewModelScope.launch { fun checkUpdate(checkUpdateRequest: CheckUpdateRequest) = viewModelScope.launch {
checkUpdate.postValue(Result.Loading()) checkUpdate.postValue(Result.Loading())
repository.checkUpdate(checkUpdateRequest).let { repository.checkUpdate(checkUpdateRequest).let {
@@ -155,6 +166,13 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
fun downloadClientCertificate() = viewModelScope.launch {
downloadcertificate.postValue(Result.Loading())
repository.downloadClientCertificate().let {
downloadcertificate.postValue(it)
}
}
fun startPeriodicCheckUpdate() { fun startPeriodicCheckUpdate() {
val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>( val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>(
repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES
@@ -178,6 +196,9 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
} }
// fun getPendingUser() = viewModelScope.launch {
// allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(true))
// }
fun uploadHemoCubeResultToDatabaseForBufferCheck( fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean, isOnline: Boolean,
@@ -282,6 +303,7 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString()
testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString() testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString()
testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString() testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString()
testDetails?.borderlineMethod2Class = DataHolder.hemoCubeTestData?.borderlineMethod2Class.toString()
testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString() testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString()
testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString()
testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString()
@@ -311,24 +333,30 @@ class HemoCubeViewModel @Inject constructor(
Log.i("Testdb", "Data uploaded to Firestore successfully") Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success") fireBaseUpload.postValue("Success")
testDetails.localFlag = true testDetails.localFlag = true
uploadResult( if (Constants.MOLBIO_INTEGRATION) {
MolbioV2ResultRequest( // Sanitize testDetails before using it in the API call
mutableListOf( val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
MolbioV2Result(
rawData = testDetails, // Now, use sanitizedTestDetails for the API call
analysisId = testDetails._id, uploadResult(
analysisDate = testDetails.testTime, MolbioV2ResultRequest(
analysisStatus = testDetails.classificationResult, mutableListOf(
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(), MolbioV2Result(
interpretation = testDetails.classificationResult, rawData = sanitizedTestDetails,
testId = testDetails._id, analysisId = sanitizedTestDetails._id,
testTime = testDetails.testTime, analysisDate = sanitizedTestDetails.testTime,
collectionTime = testDetails.testTime, analysisStatus = sanitizedTestDetails.classificationResult,
expiryTime = testDetails.testTime, thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(),
interpretation = sanitizedTestDetails.classificationResult,
testId = sanitizedTestDetails._id,
testTime = sanitizedTestDetails.testTime,
collectionTime = sanitizedTestDetails.testTime,
expiryTime = sanitizedTestDetails.testTime,
)
) )
) )
) )
) }
hemoCubeDao.insertAll(testDetails) hemoCubeDao.insertAll(testDetails)
} }
@@ -365,6 +393,19 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData {
hemoCubeTestData::class.java.declaredFields.forEach { field ->
if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) {
field.isAccessible = true
val value = field.get(hemoCubeTestData) as Double?
if (value != null && (value.isInfinite() || value.isNaN())) {
field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value
}
}
}
return hemoCubeTestData
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch { private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true) hemoCubeDao.updateFieldById(id = userId, true)
} }
@@ -397,6 +438,8 @@ class HemoCubeViewModel @Inject constructor(
Log.e("Testdb", "Error uploading data to Firestore: $response") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
} }
else -> {}
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") Log.e("Testdb", "Exception during data upload: ${e.message}")

Some files were not shown because too many files have changed in this diff Show More