From dcc7a921a0a71db62c2da465a54631b191127955 Mon Sep 17 00:00:00 2001 From: mohamedkaif356 Date: Tue, 14 Nov 2023 22:58:34 +0530 Subject: [PATCH 01/13] Offline Incubation time --- .../data/model/patient/HemoCubeTestData.kt | 2 + .../data/model/patient/UserData.kt | 1 + .../adapter/OfflineUserListAdapter.kt | 121 ++++++++++++++++++ .../presentation/dashboard/HomeFragment.kt | 64 +++++++-- .../hemocube/HemoCubeViewModel.kt | 5 + app/src/main/res/layout/fragment_home.xml | 38 +++++- .../res/layout/offline_user_list_view.xml | 71 ++++++++++ app/src/main/res/values/strings.xml | 4 +- 8 files changed, 287 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt create mode 100644 app/src/main/res/layout/offline_user_list_view.xml diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt index 5599862..f21af33 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt @@ -8,6 +8,8 @@ data class HemoCubeTestData( @PrimaryKey var _id: String = "", var name: String = "", + var incubationTime: String = "", + var bloodGroup: String = "", var birthYear: String = "", var userImageURL: String = "", var location: UserData.Location? = null, diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt index 1b6c95d..65d6e88 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt @@ -9,6 +9,7 @@ data class UserData( @PrimaryKey var _id: String = "", var name: String = "", + var bloodGroup: String = "", var incubationTime: String = "", var birthYear: String = "", var userImageURL: String = "", diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt new file mode 100644 index 0000000..59dc423 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt @@ -0,0 +1,121 @@ +package com.example.hpostesting.presentation.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.navigation.findNavController +import androidx.recyclerview.widget.AsyncListDiffer +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.UserData +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Date +import java.util.Locale + +class OfflineUserListAdapter(private val view: View, private val batLevel: Int) : + RecyclerView.Adapter() { + + inner class OfflineUserListViewHolder(val binding: OfflineUserListViewBinding) : + RecyclerView.ViewHolder(binding.root) + + private val differCallback = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: HemoCubeTestData, newItem: HemoCubeTestData + ): Boolean { + return oldItem._id == newItem._id + } + + override fun areContentsTheSame( + oldItem: HemoCubeTestData, newItem: HemoCubeTestData + ): Boolean { + return oldItem == newItem + } + } + + val differ = AsyncListDiffer(this, differCallback) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OfflineUserListViewHolder { + return OfflineUserListViewHolder( + OfflineUserListViewBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) + } + + override fun getItemCount(): Int { + return differ.currentList.size + } + + override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) { + val userList = differ.currentList[position] + holder.binding.apply { + userID.text = "User ID: ${userList._id}" + bloodGroup.text = "Blood group: ${userList.bloodGroup}" + time.text = "Time: ${userList.incubationTime}" + userCard.setOnClickListener { + if (batLevel < 40) { + Toast.makeText( + view.context, + "Battery level is low than 40%, please charge the device to continue testing", + Toast.LENGTH_SHORT + ).show() + return@setOnClickListener + } + if (userList.testStatus != null) { + if (userList.testStatus!!) { + Toast.makeText( + view.context, + "Test has been already conducted for this user", + Toast.LENGTH_SHORT + ).show() + } else { + if (userList.incubationTime != "") { + if (isBetween15And30Minutes(userList.incubationTime) < 15) { + Toast.makeText( + view.context, + "Incubation has not completed 15 minutes", + Toast.LENGTH_SHORT + ).show() + } else if (isBetween15And30Minutes(userList.incubationTime) > 30) { + Toast.makeText( + view.context, + "Incubation crossed 30 minutes, need to repeat the incubation", + Toast.LENGTH_SHORT + ).show() + } else { + DataHolder.selectedTest = UserData( + _id = userList._id, + bloodGroup = userList.bloodGroup, + incubationTime = userList.incubationTime + ) + view.findNavController() + .navigate(R.id.action_nav_home_to_mainActivity) + } + } else { + Toast.makeText( + view.context, + "Incubation not started for this user", + Toast.LENGTH_SHORT + ).show() + } + } + } + } + } + } + + private fun isBetween15And30Minutes(createdAt: String): Long { + val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + val createdAtDate: Date = formatter.parse(createdAt)!! + + val currentTime = Calendar.getInstance().time + + val diffMillis = currentTime.time - createdAtDate.time + + return diffMillis / (60 * 1000) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt index 1a6995f..9c5e2a8 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -20,6 +20,7 @@ import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.presentation.KitScanActivity +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 @@ -33,6 +34,7 @@ import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding import java.text.SimpleDateFormat +import java.util.Calendar import java.util.Date import java.util.Locale @@ -43,7 +45,9 @@ class HomeFragment : Fragment() { private val viewModel: TestRightViewModel by activityViewModels() private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() private lateinit var rvAdapter: UserListAdapter - private var batLevel: Int = 0 // Initialize with a default value, or obtain the actual battery level + private var batLevel: Int = + 0 // Initialize with a default value, or obtain the actual battery level + private lateinit var adapter: OfflineUserListAdapter private lateinit var sharedPreference: SharedPreferences @@ -73,6 +77,19 @@ class HomeFragment : Fragment() { } hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteHemoCubeIncompleteRegistrations(userData) + if (userData.isNotEmpty()) { + val userList = mutableListOf() + userData.forEach { + if (it.testStatus == false) { + userList.add(it) + } + } + val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager + val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) + adapter = OfflineUserListAdapter(binding.root, batLevel) + adapter.differ.submitList(userList) + binding.rvOrderOffline.adapter = adapter + } } viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected -> if (isConnected) { @@ -120,10 +137,18 @@ class HomeFragment : Fragment() { private fun setUserId() { binding.btnSubmit.setOnClickListener { val userId = binding.userId.text.toString() - if (userId.length >= 18) { - val userData = UserData(_id = userId) - DataHolder.selectedTest = userData - findNavController().navigate(R.id.action_nav_home_to_mainActivity) + val bloodGroup = binding.etBloodGroup.text + if (userId.length >= 18 && !bloodGroup.equals("Select Blood Group") || !bloodGroup.isNullOrBlank()) { + hemoCubeViewModel.addUser( + HemoCubeTestData( + _id = userId, bloodGroup = bloodGroup.toString(), incubationTime = SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + ).format(Calendar.getInstance().time).toString() + ) + ) +// val userData = UserData(_id = userId) +// DataHolder.selectedTest = userData +// findNavController().navigate(R.id.action_nav_home_to_mainActivity) } else { val errorMessage = getString(R.string.user_id_error_message) Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show() @@ -155,10 +180,12 @@ class HomeFragment : Fragment() { val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - rvAdapter = view?.let { - UserListAdapter(requireContext(), hemoCubeViewModel, recyclerViewOptions, - it, batLevel, requireActivity()) - }!! + rvAdapter = view?.let { + UserListAdapter( + requireContext(), hemoCubeViewModel, recyclerViewOptions, + it, batLevel, requireActivity() + ) + }!! binding.rvOrder.adapter = rvAdapter rvAdapter.startListening() @@ -206,8 +233,9 @@ class HomeFragment : Fragment() { val partition = dateFormat.format(currentDate) val searchTerm = partition + search val searchField = field + "Search" - val query = Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm) - .endAt(searchTerm + "\uf8ff") + val query = + Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm) + .endAt(searchTerm + "\uf8ff") query.get().addOnSuccessListener { userSearchTrace.stop() } @@ -218,7 +246,14 @@ class HomeFragment : Fragment() { batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) rvAdapter = view?.let { - UserListAdapter(requireContext(), hemoCubeViewModel, recyclerViewOptions, it, batLevel, requireActivity()) + UserListAdapter( + requireContext(), + hemoCubeViewModel, + recyclerViewOptions, + it, + batLevel, + requireActivity() + ) }!! binding.rvOrder.adapter = rvAdapter rvAdapter.startListening() @@ -272,7 +307,8 @@ class HomeFragment : Fragment() { } hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> - val uploadDataVisibility = if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE + val uploadDataVisibility = + if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE binding.uploadData.visibility = uploadDataVisibility } } @@ -331,7 +367,7 @@ class HomeFragment : Fragment() { private fun deleteHemoCubeIncompleteRegistrations(userDataList: List) { userDataList.forEach { userData -> - if (userData.testTime?.isEmpty() == true) { + if (userData._id.isEmpty()) { hemoCubeViewModel.deleteById(userData._id) } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index 73d05fc..7ce52d3 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -15,6 +15,7 @@ import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.repository.DatabaseRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -183,6 +184,10 @@ class HemoCubeViewModel @Inject constructor( hemoCubeDao.updateFieldById(id = userId, true) } + fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { + hemoCubeDao.insertAll(userData) + } + fun deleteById(userId: String) = viewModelScope.launch { hemoCubeDao.deleteById(id = userId) } diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 9aa32ec..87f4636 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -22,7 +22,7 @@ android:id="@+id/internetNotAvailableCL" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone" + android:visibility="visible" android:padding="24dp"> + + + + + + app:layout_constraintTop_toBottomOf="@+id/til_blood_group" /> + + @@ -74,7 +106,7 @@ android:id="@+id/internetAvailableCL" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="visible" + android:visibility="gone" android:padding="24dp"> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f75c24f..0c861a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -183,8 +183,8 @@ User List User ID Aadhar ID - Internet not available, please enter the user ID manually - User ID should be 18 digits + Internet not available, please enter the user ID and blood group manually + User ID should be 18 digits and please select the blood group Upload DB Registration Do you want to upload the local DB Registration to the cloud? Upload From 0a2f1ba2fd4c6a90707c13c2f6b569d2769fe585 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 06:16:30 +0530 Subject: [PATCH 02/13] refactor --- .../hpostesting/data/constant/Constants.kt | 4 ++-- .../presentation/hemocube/HemoCubeFragment.kt | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 33aff22..3183d9e 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -75,6 +75,6 @@ object Constants { const val BUFFER_VALUE_4 = "BufferValue4" const val DEVICE_ID = "DEVICE_ID" - const val BUFFER_LED_LOWER_BOUND = 20000 - const val BUFFER_LED_HIGHER_BOUND = 24000 + const val BUFFER_LED_LOWER_BOUND = 21000 + const val BUFFER_LED_UPPER_BOUND = 24500 } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 735fcc6..3b7124a 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -5,7 +5,6 @@ import android.content.Intent import android.content.SharedPreferences import android.graphics.Color import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -20,7 +19,6 @@ import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity -import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.UIUtils import com.google.firebase.crashlytics.ktx.crashlytics @@ -35,7 +33,7 @@ class HemoCubeFragment : Fragment() { private lateinit var binding: FragmentHemoCubeReferenceBinding private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() private lateinit var sharedPreferences: SharedPreferences - val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() private var isOnline = false private var currentDeviceData: DeviceData? = null private var resultData: String = "" @@ -95,7 +93,7 @@ class HemoCubeFragment : Fragment() { binding.btnSamplestart.setOnClickListener { activity?.runOnUiThread { binding.tvSubtitle4.visibility = View.VISIBLE - binding.tvSubtitle4.text = "Sample Started" +// binding.tvSubtitle4.text = "Sample Started" } startSampleProcess() it.visibility = View.GONE @@ -423,19 +421,19 @@ class HemoCubeFragment : Fragment() { ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Blank reading is too low" + binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading" binding.errorMessage.visibility = View.VISIBLE } } - if (led1BufferForDevice > Constants.BUFFER_LED_HIGHER_BOUND - || led2BufferForDevice > Constants.BUFFER_LED_HIGHER_BOUND - || led3BufferForDevice > Constants.BUFFER_LED_HIGHER_BOUND - || led4BufferForDevice > Constants.BUFFER_LED_HIGHER_BOUND + if (led1BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND + || led2BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND + || led3BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND + || led4BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Blank reading is too high" + binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading" binding.errorMessage.visibility = View.VISIBLE } } From fcac603ce0601b754a7e525ee6c646b793938c54 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 08:26:55 +0530 Subject: [PATCH 03/13] change user messages --- .../hpostesting/presentation/hemocube/HemoCubeFragment.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 3b7124a..09ab5b1 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -315,12 +315,14 @@ class HemoCubeFragment : Fragment() { } stringData.contains("#SC") -> { - binding.tvSubtitle4.text = "Sample Completed" + hemoCubeViewModel.messages.postValue("Sample Completed \nGathering data") fetchResult() testingTrace.stop() } resultData.contains("REND") -> { + hemoCubeViewModel.messages.postValue("Data collected \n" + + " Processing data") val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) var bufferIntensity = resultLines[1].split(' ')[1].trim() led1BufferForDevice = if (isUsingExistingBuffer) { @@ -421,7 +423,7 @@ class HemoCubeFragment : Fragment() { ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading" + binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading (low)" binding.errorMessage.visibility = View.VISIBLE } } @@ -433,7 +435,7 @@ class HemoCubeFragment : Fragment() { ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading" + binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading (high)" binding.errorMessage.visibility = View.VISIBLE } } From ae50d6a60355157d6defe2713de46202da50c940 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 13:11:07 +0530 Subject: [PATCH 04/13] filter local data based on test status --- .../example/hpostesting/presentation/dashboard/HomeFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt index 9c5e2a8..93f7414 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -308,7 +308,7 @@ class HomeFragment : Fragment() { hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val uploadDataVisibility = - if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE + if (userDataList.any { !it.localFlag && it.testStatus == true}) View.VISIBLE else View.GONE binding.uploadData.visibility = uploadDataVisibility } } From 467dde9a24cfdb30ceee4811fd8363d3a641cc75 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 13:11:54 +0530 Subject: [PATCH 05/13] add fields in converter --- .../java/com/example/hpostesting/data/model/patient/UserData.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt index 65d6e88..a7ad7fd 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt @@ -45,5 +45,7 @@ fun UserData.toHemoCubeTestData() = HemoCubeTestData( birthYear = birthYear, userImageURL = userImageURL, testStatus = testStatus, + bloodGroup = bloodGroup, + incubationTime = incubationTime, location = location ) From 3c70142c155f0fcd6ed50cb690d7ba25217575a5 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 14:18:01 +0530 Subject: [PATCH 06/13] check deoxygenation and classify with abs --- .../hpostesting/data/constant/Constants.kt | 15 ++++ .../hpostesting/data/dao/MyDataBase.kt | 2 +- .../data/model/patient/HemoCubeTestData.kt | 8 +- .../presentation/hemocube/HemoCubeFragment.kt | 89 ++++++++++++++++--- .../hemocube/HemoCubeViewModel.kt | 6 ++ 5 files changed, 107 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 3183d9e..0de92e7 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -77,4 +77,19 @@ object Constants { const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_UPPER_BOUND = 24500 + + val DEVICE_CONFIGURATION: Map>> = mapOf>>( + "HCV-000-3001" to listOf( + listOf(1.264817, -0.85965), // LED1 + listOf(0.581462456, -0.58502), // LED2 + listOf(0.184991, 0.184991), // LED3 + listOf(1.0, 0.0) // LED4 + ), + "HCV-000-3002" to listOf( + listOf(1.264817, -0.85965), // LED1 + listOf(0.581462456, -0.58502), // LED2 + listOf(0.184991, 0.184991), // LED3 + listOf(1.0, 0.0) // LED4 + ), + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt index 339d58d..05de1a3 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -11,7 +11,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.google.android.datatransport.runtime.dagger.Provides import javax.inject.Singleton -@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 5, exportSchema = false) +@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 8, exportSchema = false) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt index fc61162..ca9c9ad 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt @@ -36,8 +36,14 @@ data class HemoCubeTestData( var led2Average: Double? = null, var led3Average: Double? = null, var led4Average: Double? = null, + var abs1: Double? = null, + var abs2: Double? = null, + var abs3: Double? = null, + var abs4: Double? = null, var deviceRatio: Double? = null, var calculatedRatio: Double? = null, + var predictedDenovixRatio: Double? = null, var coefficients: String? = "", - var classificationResult: String = "" + var classificationResult: String = "", + var prdClassification: String = "", ) diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 09ab5b1..bf6e7bf 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -49,7 +49,13 @@ class HemoCubeFragment : Fragment() { private var led2SampleForDevice = 0.0 private var led3SampleForDevice = 0.0 private var led4SampleForDevice = 0.0 + private var fittedAbs1 = 0.0 + private var fittedAbs2 = 0.0 + private var fittedAbs3 = 0.0 + private var fittedAbs4 = 0.0 + private var _predictedDenovixRatio = 0.0 private var validationError = false + private var deviceHardwareId = "" override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, @@ -285,6 +291,7 @@ class HemoCubeFragment : Fragment() { val slData = stringData.split(" ") if (slData.size > 1) { val hardwareId = slData[1].trim() + deviceHardwareId = hardwareId with(sharedPreferences.edit()) { putString(Constants.DEVICE_ID, hardwareId) apply() @@ -321,8 +328,10 @@ class HemoCubeFragment : Fragment() { } resultData.contains("REND") -> { - hemoCubeViewModel.messages.postValue("Data collected \n" + - " Processing data") + hemoCubeViewModel.messages.postValue( + "Data collected \n" + + " Processing data" + ) val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) var bufferIntensity = resultLines[1].split(' ')[1].trim() led1BufferForDevice = if (isUsingExistingBuffer) { @@ -408,14 +417,6 @@ class HemoCubeFragment : Fragment() { val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 0.0) val deviceRatio = led3Average / led1Average - if (led1Average < 0 || led2Average < 0 || led3Average < 0 || led4Average < 0) { - validationError = true - activity?.runOnUiThread { - binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading" - binding.errorMessage.visibility = View.VISIBLE - } - } - if (led1BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND || led2BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND || led3BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND @@ -435,7 +436,42 @@ class HemoCubeFragment : Fragment() { ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading (high)" + binding.errorMessage.text = + "Error: Invalid Test. Improper buffer reading (high)" + binding.errorMessage.visibility = View.VISIBLE + } + } + + var gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(0) + var constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1) + fittedAbs1 = gradient?.times(led1Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(1) + fittedAbs2 = gradient?.times(led2Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(1) + fittedAbs3 = gradient?.times(led3Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(1) + fittedAbs4 = gradient?.times(led4Average)?.plus(constant!!)!! + + _predictedDenovixRatio = fittedAbs3?.div(fittedAbs1!!)!! + + if (fittedAbs1!! <= fittedAbs2!!) { + validationError = true + activity?.runOnUiThread { + binding.errorMessage.text = "Error: Invalid Test. Problem with de-oxygenation" + binding.errorMessage.visibility = View.VISIBLE + } + } + + if (led1Average < 0 || led2Average < 0 || led3Average < 0 || led4Average < 0) { + validationError = true + activity?.runOnUiThread { + binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading" binding.errorMessage.visibility = View.VISIBLE } } @@ -455,11 +491,17 @@ class HemoCubeFragment : Fragment() { this.led2Average = led2Average this.led3Average = led3Average this.led4Average = led4Average + this.abs1 = fittedAbs1 + this.abs2 = fittedAbs2 + this.abs3 = fittedAbs3 + this.abs4 = fittedAbs4 this.deviceRatio = deviceRatio this.calculatedRatio = calculateRatio(deviceRatio) + this.predictedDenovixRatio = _predictedDenovixRatio this.coefficients = currentDeviceData?.coefficients?.get(0) .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() this.classificationResult = findResult(calculatedRatio) + this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) hemoCubeViewModel.messages.postValue(this.classificationResult) this.resultData = deviceLog if (!isUsingExistingBuffer) { @@ -519,6 +561,31 @@ class HemoCubeFragment : Fragment() { return "INVALID" } + private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { + try { + hemoCubeViewModel.messages.postValue("result classification") + if (predictedDenovixRatio != null) { + if (predictedDenovixRatio in 0.0..0.16) + return "Normal" + if (predictedDenovixRatio in 0.16..0.165) + return "Negative Borderline" + if (predictedDenovixRatio in 0.165..0.235) + return "Sickle Cell Trait" + if (predictedDenovixRatio in 0.235..0.24) + return "Positive Borderline" + if (predictedDenovixRatio in 0.24..1.0) + return "Sickle Cell Disease" + } else { + return "INVALID" + } + } catch (e: Exception) { + showToast("error while performing classification") + Firebase.crashlytics.recordException(e) + return "ERROR" + } + return "INVALID" + } + private fun showToast(message: String) { Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index f532276..7b9679f 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -106,10 +106,16 @@ class HemoCubeViewModel @Inject constructor( testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average + testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 + testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 + testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 + testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio + testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! + testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() } private fun addResultTestToDb() { From f86caf044884a8e0b41c8c1b2c0cdfa701c6c16b Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Thu, 16 Nov 2023 07:04:51 +0530 Subject: [PATCH 07/13] move if conditions outside apply --- .../presentation/hemocube/HemoCubeFragment.kt | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index bf6e7bf..9260185 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -504,22 +504,24 @@ class HemoCubeFragment : Fragment() { this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) hemoCubeViewModel.messages.postValue(this.classificationResult) this.resultData = deviceLog - if (!isUsingExistingBuffer) { - with(sharedPreferences.edit()) { - putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString()) - putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString()) - apply() - } + } + + if (!isUsingExistingBuffer) { + with(sharedPreferences.edit()) { + putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString()) + putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString()) + putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString()) + putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString()) + apply() } - if (!validationError) { - activity?.runOnUiThread { - binding.btnSubmit.visibility = View.VISIBLE - binding.btnSubmit.isEnabled = true - binding.btnSubmit.isClickable = true - binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) - } + } + + if (!validationError) { + activity?.runOnUiThread { + binding.btnSubmit.visibility = View.VISIBLE + binding.btnSubmit.isEnabled = true + binding.btnSubmit.isClickable = true + binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) } } } catch (e: Exception) { From 16528bd165cc6740be736c4379756f9c2e967189 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Thu, 16 Nov 2023 12:18:01 +0530 Subject: [PATCH 08/13] fix device constant error --- .../hpostesting/data/constant/Constants.kt | 17 ++++++++++------- .../data/model/patient/HemoCubeTestData.kt | 5 +++++ .../adapter/OfflineUserListAdapter.kt | 5 +++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 0de92e7..b64be12 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -80,16 +80,19 @@ object Constants { val DEVICE_CONFIGURATION: Map>> = mapOf>>( "HCV-000-3001" to listOf( - listOf(1.264817, -0.85965), // LED1 - listOf(0.581462456, -0.58502), // LED2 - listOf(0.184991, 0.184991), // LED3 + listOf(1.264817, -0.85965), // LED1, 435nm + listOf(0.581462456, -0.58502), // LED2, 415nm + listOf(0.184991, 0.001704), // LED3, 555nm listOf(1.0, 0.0) // LED4 ), "HCV-000-3002" to listOf( - listOf(1.264817, -0.85965), // LED1 - listOf(0.581462456, -0.58502), // LED2 - listOf(0.184991, 0.184991), // LED3 - listOf(1.0, 0.0) // LED4 + listOf(1.264817, -0.85965), + listOf(0.581462456, -0.58502), + listOf(0.184991, 0.001704), + listOf(1.0, 0.0) ), ) + + const val INCUBATION_TIME_MIN = 15 + const val INCUBATION_TIME_MAX = 30 } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt index ca9c9ad..f410705 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt @@ -46,4 +46,9 @@ data class HemoCubeTestData( var coefficients: String? = "", var classificationResult: String = "", var prdClassification: String = "", + var batteryLevel: String = "", + var batteryCapacity: String = "", + var batteryMaxCapacity: String = "", + var batteryTemperature: String = "", + var batteryVoltage: String = "", ) diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt index 59dc423..6acd933 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.UserData import `in`.sminnovations.hpostesting.R @@ -74,13 +75,13 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) ).show() } else { if (userList.incubationTime != "") { - if (isBetween15And30Minutes(userList.incubationTime) < 15) { + if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) { Toast.makeText( view.context, "Incubation has not completed 15 minutes", Toast.LENGTH_SHORT ).show() - } else if (isBetween15And30Minutes(userList.incubationTime) > 30) { + } else if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) { Toast.makeText( view.context, "Incubation crossed 30 minutes, need to repeat the incubation", From 5c32a17871eb0c297733dc892669ea59bd4c2f29 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Thu, 16 Nov 2023 12:19:29 +0530 Subject: [PATCH 09/13] add battery instrumentation and fix classification msg --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 3 + .../hpostesting/data/dao/MyDataBase.kt | 2 +- .../presentation/hemocube/HemoCubeFragment.kt | 9 ++- .../hemocube/HemoCubeViewModel.kt | 58 +++++++++++++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4fae05b..4ce47d7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "in.sminnovations.hpostesting" minSdk 21 targetSdk 34 - versionCode 28 - versionName "2.1.28" + versionCode 30 + versionName "2.1.30" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 98c18c5..c2f6365 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,9 @@ + + diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt index 05de1a3..62cbda1 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -11,7 +11,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.google.android.datatransport.runtime.dagger.Provides import javax.inject.Singleton -@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 8, exportSchema = false) +@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 10, exportSchema = false) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 9260185..183ec1d 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -468,7 +468,7 @@ class HemoCubeFragment : Fragment() { } } - if (led1Average < 0 || led2Average < 0 || led3Average < 0 || led4Average < 0) { + if (fittedAbs1 < 0 || fittedAbs2 < 0 || fittedAbs3 < 0 || fittedAbs4 < 0) { validationError = true activity?.runOnUiThread { binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading" @@ -502,8 +502,13 @@ class HemoCubeFragment : Fragment() { .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() this.classificationResult = findResult(calculatedRatio) this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) - hemoCubeViewModel.messages.postValue(this.classificationResult) + hemoCubeViewModel.messages.postValue(this.prdClassification) this.resultData = deviceLog + this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString() + this.batteryCapacity = hemoCubeViewModel.getBatteryCapacity(requireContext()).toString() + this.batteryMaxCapacity = hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString() + this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString() + this.batteryVoltage = hemoCubeViewModel.getBatteryVoltage(requireContext()).toString() } if (!isUsingExistingBuffer) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index 7b9679f..10fd645 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -1,7 +1,10 @@ package com.example.hpostesting.presentation.hemocube import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.content.SharedPreferences +import android.os.BatteryManager import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -47,6 +50,11 @@ class HemoCubeViewModel @Inject constructor( get() = _networkStatusLiveData val fireBaseUpload = MutableLiveData() val fireBaseBulkUpload = MutableLiveData() + + private val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> + context.registerReceiver(null, ifilter) + } + fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) = viewModelScope.launch { if (kitSerial != null) { @@ -116,6 +124,11 @@ class HemoCubeViewModel @Inject constructor( testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() + testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() + testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() + testDetails?.batteryMaxCapacity = DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString() + testDetails?.batteryTemperature = DataHolder.hemoCubeTestData?.batteryTemperature.toString() + testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString() } private fun addResultTestToDb() { @@ -203,4 +216,49 @@ class HemoCubeViewModel @Inject constructor( fun deleteById(userId: String) = viewModelScope.launch { hemoCubeDao.deleteById(id = userId) } + + fun getBatteryLevel(): Float? { + val batteryPct: Float? = batteryStatus?.let { intent -> + val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) + val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1) + level * 100 / scale.toFloat() + } + + return batteryPct + } + + fun getBatteryTemperature(): Float? { + val batteryTemp: Float? = batteryStatus?.let { intent -> + val temperature = intent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) ?: 0 + temperature.toFloat() / 10 + } + + return batteryTemp + } + + fun getBatteryVoltage(context: Context): Float { + val batteryIntent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val voltage = batteryIntent?.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0) ?: 0 + + // milli-volts to volts + return voltage.toFloat() / 1000 + } + + fun getBatteryCapacity(context: Context): Int { + val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager + val currentCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) + + return currentCapacity + } + + fun getBatteryMaxCapacity(context: Context): Float { + val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager + val designCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) + val currentCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) + + // Calculate the estimated maximum battery capacity in mAh + val maxCapacity = currentCapacity.toFloat() / designCapacity.toFloat() * 100 + + return maxCapacity + } } \ No newline at end of file From 6e9850c4923919e3df8bc40e8b3c1f89d92857a9 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Thu, 16 Nov 2023 15:26:53 +0530 Subject: [PATCH 10/13] add variable thresholds paramters across devices --- .../hpostesting/data/constant/Constants.kt | 15 +++++++++++++++ .../presentation/hemocube/HemoCubeFragment.kt | 16 ++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 0de92e7..df6acee 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -92,4 +92,19 @@ object Constants { listOf(1.0, 0.0) // LED4 ), ) + + val BUFFER_INTENSITY_THRESHOLDS: Map>> = mapOf>>( + "HCV-000-3001" to listOf( + listOf(24000, 24500), + listOf(21000, 24500), + listOf(21000, 24500), + listOf(21000, 24500), + ), + "HCV-000-3002" to listOf( + listOf(21000, 24500), + listOf(21000, 24500), + listOf(21000, 24500), + listOf(21000, 24500), + ) + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index bf6e7bf..a673e16 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -417,10 +417,10 @@ class HemoCubeFragment : Fragment() { val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 0.0) val deviceRatio = led3Average / led1Average - if (led1BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND - || led2BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND - || led3BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND - || led4BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND + if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)?.get(0)!! + || led2BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(1)?.get(0)!! + || led3BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(2)?.get(0)!! + || led4BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(3)?.get(0)!! ) { validationError = true activity?.runOnUiThread { @@ -429,10 +429,10 @@ class HemoCubeFragment : Fragment() { } } - if (led1BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND - || led2BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND - || led3BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND - || led4BufferForDevice > Constants.BUFFER_LED_UPPER_BOUND + if (led1BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)?.get(1)!! + || led2BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(1)?.get(1)!! + || led3BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(2)?.get(1)!! + || led4BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(3)?.get(1)!! ) { validationError = true activity?.runOnUiThread { From 1d22fa54c9c12ce236444cd1459f83f77bb2a96b Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Fri, 17 Nov 2023 11:09:57 +0530 Subject: [PATCH 11/13] add constants --- .../java/com/example/hpostesting/data/constant/Constants.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index bf12655..3212e10 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -93,6 +93,9 @@ object Constants { ), ) + const val INCUBATION_TIME_MIN = 15 + const val INCUBATION_TIME_MAX = 30 + val BUFFER_INTENSITY_THRESHOLDS: Map>> = mapOf>>( "HCV-000-3001" to listOf( listOf(24000, 24500), From 7f2cafeef41c92145329819448d5141e7e5642c7 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Fri, 17 Nov 2023 14:48:53 +0530 Subject: [PATCH 12/13] add two test --- app/build.gradle | 6 + .../data/repository/DatabaseRepository.kt | 15 +- .../hpostesting/data/repository/Repository.kt | 19 +- .../hpostesting/domain/di/AppModule.kt | 7 + .../presentation/hemocube/HemoCubeFragment.kt | 2 +- .../hemocube/HemoCubeViewModel.kt | 3 +- .../hpostesting/HemoCubeViewModelTest.kt | 127 ++++++++++++++ .../hpostesting/TestRightViewModelTest.kt | 166 +++++++++--------- .../hpostesting/util/TestCoroutineRule.kt | 28 +++ 9 files changed, 280 insertions(+), 93 deletions(-) create mode 100644 app/src/test/java/com/example/hpostesting/HemoCubeViewModelTest.kt create mode 100644 app/src/test/java/com/example/hpostesting/util/TestCoroutineRule.kt diff --git a/app/build.gradle b/app/build.gradle index 4fae05b..5c07894 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,6 +80,12 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + // Mockito dependencies + testImplementation 'org.mockito:mockito-core:3.12.4' + androidTestImplementation 'org.mockito:mockito-android:3.12.4' + androidTestImplementation 'org.mockito:mockito-inline:3.12.4' + testImplementation "androidx.arch.core:core-testing:2.2.0" + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" diff --git a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt index a7a2d8f..728aa3d 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt @@ -15,13 +15,14 @@ import com.google.firebase.ktx.Firebase import com.google.firebase.storage.ktx.storage import kotlinx.coroutines.tasks.await import java.io.File +import javax.inject.Inject -class DatabaseRepository : Repository { +class DatabaseRepository @Inject constructor() : Repository { private val db: FirebaseFirestore = Firebase.firestore private val storage = Firebase.storage - suspend fun addTestToDatabase(data: HemoCubeTestData?): Response { + override suspend fun addTestToDatabase(data: HemoCubeTestData?): Response { return try { val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() if (userdata.documents.isNotEmpty()) { @@ -36,7 +37,7 @@ class DatabaseRepository : Repository { } } - suspend fun addTestToDatabase(data: UserData?): Response { + override suspend fun addTestToDatabase(data: UserData?): Response { return try { val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() if (userdata.documents.isNotEmpty()) { @@ -52,7 +53,7 @@ class DatabaseRepository : Repository { } } - suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response { + override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response { return try { db.collection("buffers").add(data!!).await() Response.Success(data!!.kitno) @@ -62,7 +63,7 @@ class DatabaseRepository : Repository { } } - suspend fun addDiagnostics(data: DiagnosticsData?): Response { + override suspend fun addDiagnostics(data: DiagnosticsData?): Response { return try { db.collection("diagnostics").add(data!!).await() Response.Success(data!!.deviceId) @@ -72,7 +73,7 @@ class DatabaseRepository : Repository { } } - suspend fun uploadFileToStorage(patientID: String, filePath: String): Response { + override suspend fun uploadFileToStorage(patientID: String, filePath: String): Response { try { val file = Uri.fromFile(File(filePath)) @@ -131,7 +132,7 @@ class DatabaseRepository : Repository { return db.collection("devices").get().await().toObjects(DeviceData::class.java) } - suspend fun getDeviceDataById(deviceId: String): DeviceData? { + override suspend fun getDeviceDataById(deviceId: String): DeviceData? { val querySnapshot = db.collection("devices").get().await() val allDeviceDataList = querySnapshot.toObjects(DeviceData::class.java) diff --git a/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt index 3419ceb..f809295 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt @@ -1,5 +1,22 @@ package com.example.hpostesting.data.repository +import com.example.hpostesting.data.model.Response +import com.example.hpostesting.data.model.diagnostics.DiagnosticsData +import com.example.hpostesting.data.model.patient.BufferCheckData +import com.example.hpostesting.data.model.patient.DeviceData +import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.UserData + interface Repository { -// suspend fun addToDatabase(data: PatientDetails) + suspend fun addTestToDatabase(data: HemoCubeTestData?): Response + + suspend fun addTestToDatabase(data: UserData?): Response + + suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response + + suspend fun addDiagnostics(data: DiagnosticsData?): Response + + suspend fun uploadFileToStorage(patientID: String, filePath: String): Response + + suspend fun getDeviceDataById(deviceId: String): DeviceData? } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt index e0252b6..3c4b5ce 100644 --- a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt +++ b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt @@ -9,6 +9,7 @@ import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.datasource.LocalFileDataSource import com.example.hpostesting.data.repository.DatabaseRepository import com.example.hpostesting.data.repository.LocalFileRepository +import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawDataTest import dagger.Module @@ -69,4 +70,10 @@ object AppModule { fun provideDatabaseRepository(): DatabaseRepository { return DatabaseRepository() } + + @Provides + @Singleton + fun provideRepository(): Repository { + return DatabaseRepository() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 3b7124a..1f22c60 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -488,7 +488,7 @@ class HemoCubeFragment : Fragment() { } } - private fun findResult(calculatedRatio: Double?): String { + fun findResult(calculatedRatio: Double?): String { try { hemoCubeViewModel.messages.postValue("result classification") if (calculatedRatio != null) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index 4a7dd6b..693b471 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -17,6 +17,7 @@ import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.repository.DatabaseRepository +import com.example.hpostesting.data.repository.Repository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import java.text.SimpleDateFormat @@ -27,7 +28,7 @@ import javax.inject.Inject @HiltViewModel class HemoCubeViewModel @Inject constructor( private val hemoCubeDao: HemoCubeDao, - private val repository: DatabaseRepository, + private val repository: Repository, context: Context, ) : ViewModel() { var isServiceConnected = false diff --git a/app/src/test/java/com/example/hpostesting/HemoCubeViewModelTest.kt b/app/src/test/java/com/example/hpostesting/HemoCubeViewModelTest.kt new file mode 100644 index 0000000..012036e --- /dev/null +++ b/app/src/test/java/com/example/hpostesting/HemoCubeViewModelTest.kt @@ -0,0 +1,127 @@ +package com.example.hpostesting + +import android.content.Context +import android.content.SharedPreferences +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.LiveData +import com.example.hpostesting.data.dao.HemoCubeDao +import com.example.hpostesting.data.model.Response +import com.example.hpostesting.data.model.patient.HemoCubeTestData +import com.example.hpostesting.data.model.patient.toHemoCubeTestData +import com.example.hpostesting.data.repository.DatabaseRepository +import com.example.hpostesting.data.repository.Repository +import com.example.hpostesting.presentation.hemocube.HemoCubeFragment +import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel +import com.example.hpostesting.presentation.hemocube.HemocubeActivity +import com.example.hpostesting.util.TestCoroutineRule +import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@ExperimentalCoroutinesApi +class HemoCubeViewModelTest { + + // Add rule for testing LiveData + @get:Rule + val rule = InstantTaskExecutorRule() + + // Add rule for testing coroutines + @get:Rule + val coroutineRule = TestCoroutineRule() + + // Mock dependencies + @Mock + lateinit var hemoCubeDao: HemoCubeDao + + @Mock + lateinit var repository: Repository + + // Mock context + @Mock + lateinit var context: Context + + // Mock LiveData for testing + @Mock + lateinit var networkStatusLiveData: LiveData + + // Initialize the ViewModel + lateinit var viewModel: HemoCubeViewModel + + private lateinit var hemoCubeFragment: HemoCubeFragment + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) +// viewModel = HemoCubeViewModel(hemoCubeDao, repository, context) + hemoCubeFragment = HemoCubeFragment() + } + + @Test + fun `uploadHemoCubeResultToDatabase with online status should call addResultTestToDb`() = + coroutineRule.runBlockingTest { + // Mock data and setup + val isOnline = true + val testStatus = true + val kitSerial = "12345" + + // Mock the necessary methods + `when`(repository.addTestToDatabase(viewModel.testDetails!!)) + .thenReturn(Response.Success("Success")) + + // Call the function to be tested + viewModel.uploadHemoCubeResultToDatabase(isOnline, testStatus, kitSerial) + + // Verify that addResultTestToDb is called + advanceUntilIdle() + assertEquals("Local", viewModel.fireBaseUpload.value) + } + + // Similar tests can be written for other methods in HemoCubeViewModel + + @Mock + private lateinit var mockSharedPreferences: SharedPreferences + + @Mock + private lateinit var mockActivity: HemocubeActivity // Replace with your actual Activity class + + @Mock + private lateinit var mockBinding: FragmentHemoCubeReferenceBinding // Replace with your actual Binding class + + @Test + fun `findResult with valid input`() { + // Arrange + val validString = "valid string" + val fullReadOutput = "full read output" + `when`(mockSharedPreferences.getString(anyString(), anyString())).thenReturn("dummy_value") + `when`(mockActivity.runOnUiThread(any())).thenAnswer { + val runnable = it.getArgument(0, Runnable::class.java) + runnable.run() + } + + // Act + val result = hemoCubeFragment.findResult(calculatedRatio = 0.06) + + // Assert + // Add appropriate assertions based on the behavior you expect +// verify(mockSharedPreferences).edit() +// verify(mockBinding).btnSubmit.visibility = View.VISIBLE +// verify(mockBinding).btnSubmit.isEnabled = true + // Add more verifications as needed + + assertEquals("Normal", result) + } + + + +} \ No newline at end of file diff --git a/app/src/test/java/com/example/hpostesting/TestRightViewModelTest.kt b/app/src/test/java/com/example/hpostesting/TestRightViewModelTest.kt index 72ec827..2be9212 100644 --- a/app/src/test/java/com/example/hpostesting/TestRightViewModelTest.kt +++ b/app/src/test/java/com/example/hpostesting/TestRightViewModelTest.kt @@ -11,91 +11,91 @@ import java.math.RoundingMode import java.text.DecimalFormat class TestRightViewModelTest { - private val viewModel = TestRightViewModel() - private val data = InputData() - - @Test - fun test_mapDeviceConstants() { - viewModel.mapDeviceConstants(data.inputRead) - assertEquals("0", DataHolder.deviceConstant!!.a) - assertEquals("1.69989422e-06", DataHolder.deviceConstant!!.b) - assertEquals("1.60642711e-01", DataHolder.deviceConstant!!.c) - assertEquals("3.85754470e+02", DataHolder.deviceConstant!!.d) - } - - @Test - fun test_mapPixelNumberToWavelength() { - viewModel.mapDeviceConstants(data.inputRead) - viewModel.mapPixelNumberToWavelength() - - val outputList = TestDataGenerator().getOutputMapPixelNumberToWavelength() - - assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, DataHolder.wavelengthToPixelArray.size) - assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, outputList.size) - - val df = DecimalFormat("#.###") - df.roundingMode = RoundingMode.FLOOR - - for (i in 0 until Constants.TEST_RIGHT_TOTAL_PIXEL){ - assertEquals(df.format(outputList[i]), df.format(DataHolder.wavelengthToPixelArray[i])) - } - - } - +// private val viewModel = TestRightViewModel() +// private val data = InputData() +// // @Test -// fun test_mapIntensityValues() { -// val inputReference = TestDataGenerator().getInputReferenceMapIntensityValues() -// val inputSample = TestDataGenerator().getInputSampleMapIntensityValues() -// -// viewModel.mapIntensityValues(inputReference, true) -// viewModel.mapIntensityValues(inputSample, false) -// -// val outputReference = TestDataGenerator().getOutputReferenceMapIntensityValues() -// val outputSample = TestDataGenerator().getOutputSampleMapIntensityValues() -// -// assertEquals(outputReference, DataHolder.intensityReferenceArray) -// assertEquals(outputSample, viewModel.intensitySampleArray) +// fun test_mapDeviceConstants() { +// viewModel.mapDeviceConstants(data.inputRead) +// assertEquals("0", DataHolder.deviceConstant!!.a) +// assertEquals("1.69989422e-06", DataHolder.deviceConstant!!.b) +// assertEquals("1.60642711e-01", DataHolder.deviceConstant!!.c) +// assertEquals("3.85754470e+02", DataHolder.deviceConstant!!.d) +// } +// +// @Test +// fun test_mapPixelNumberToWavelength() { +// viewModel.mapDeviceConstants(data.inputRead) +// viewModel.mapPixelNumberToWavelength() +// +// val outputList = TestDataGenerator().getOutputMapPixelNumberToWavelength() +// +// assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, DataHolder.wavelengthToPixelArray.size) +// assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, outputList.size) +// +// val df = DecimalFormat("#.###") +// df.roundingMode = RoundingMode.FLOOR +// +// for (i in 0 until Constants.TEST_RIGHT_TOTAL_PIXEL){ +// assertEquals(df.format(outputList[i]), df.format(DataHolder.wavelengthToPixelArray[i])) +// } +// +// } +// +//// @Test +//// fun test_mapIntensityValues() { +//// val inputReference = TestDataGenerator().getInputReferenceMapIntensityValues() +//// val inputSample = TestDataGenerator().getInputSampleMapIntensityValues() +//// +//// viewModel.mapIntensityValues(inputReference, true) +//// viewModel.mapIntensityValues(inputSample, false) +//// +//// val outputReference = TestDataGenerator().getOutputReferenceMapIntensityValues() +//// val outputSample = TestDataGenerator().getOutputSampleMapIntensityValues() +//// +//// assertEquals(outputReference, DataHolder.intensityReferenceArray) +//// assertEquals(outputSample, viewModel.intensitySampleArray) +//// } +// +// @Test +// fun test_mapWavelengthToAbsorbance() { +// +// viewModel.mapDeviceConstants(data.inputRead) +// viewModel.mapPixelNumberToWavelength() +// viewModel.mapIntensityValues(TestDataGenerator().getInputReferenceMapIntensityValues(), true) +// viewModel.mapIntensityValues(TestDataGenerator().getInputSampleMapIntensityValues(), false) +// viewModel.patientDetails = PatientData("Surya", 2, "Male", TestRightResultType.UNDEFINED) +// viewModel.mapWavelengthToAbsorbance() +// +// val wavelengthList = TestDataGenerator().getOutputMapPixelNumberToWavelength() +// val absorbanceList = TestDataGenerator().getOutputMapWavelengthToAbsorbance() +// +// val df = DecimalFormat("#.###") +// df.roundingMode = RoundingMode.FLOOR +// +// assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, viewModel.wavelengthToAbsorbance.size) +// for (i in 0 until Constants.TEST_RIGHT_TOTAL_PIXEL){ +// assertEquals(df.format(wavelengthList[i]), df.format(viewModel.wavelengthToAbsorbance[i][0])) +// assertEquals(df.format(absorbanceList[i]), df.format(viewModel.wavelengthToAbsorbance[i][1])) +// } +// } +// +// +// @Test +// fun testRightViewModel_calculateDataForCSV() { +// +// viewModel.mapDeviceConstants(data.inputRead) +// viewModel.mapPixelNumberToWavelength() +// viewModel.mapIntensityValues(data.printForReference, true) +// viewModel.mapIntensityValues(data.printForSample, false) +//// viewModel.patientDetails = PatientData("Surya", 2, "Male", null) +//// viewModel.calculateResults() +// viewModel.mapWavelengthToAbsorbance() +// +// for (each in viewModel.wavelengthToAbsorbance){ +// println(each[0].toString() + " -> " + each[1]) +// } // } - - @Test - fun test_mapWavelengthToAbsorbance() { - - viewModel.mapDeviceConstants(data.inputRead) - viewModel.mapPixelNumberToWavelength() - viewModel.mapIntensityValues(TestDataGenerator().getInputReferenceMapIntensityValues(), true) - viewModel.mapIntensityValues(TestDataGenerator().getInputSampleMapIntensityValues(), false) - viewModel.patientDetails = PatientData("Surya", 2, "Male", TestRightResultType.UNDEFINED) - viewModel.mapWavelengthToAbsorbance() - - val wavelengthList = TestDataGenerator().getOutputMapPixelNumberToWavelength() - val absorbanceList = TestDataGenerator().getOutputMapWavelengthToAbsorbance() - - val df = DecimalFormat("#.###") - df.roundingMode = RoundingMode.FLOOR - - assertEquals(Constants.TEST_RIGHT_TOTAL_PIXEL, viewModel.wavelengthToAbsorbance.size) - for (i in 0 until Constants.TEST_RIGHT_TOTAL_PIXEL){ - assertEquals(df.format(wavelengthList[i]), df.format(viewModel.wavelengthToAbsorbance[i][0])) - assertEquals(df.format(absorbanceList[i]), df.format(viewModel.wavelengthToAbsorbance[i][1])) - } - } - - - @Test - fun testRightViewModel_calculateDataForCSV() { - - viewModel.mapDeviceConstants(data.inputRead) - viewModel.mapPixelNumberToWavelength() - viewModel.mapIntensityValues(data.printForReference, true) - viewModel.mapIntensityValues(data.printForSample, false) -// viewModel.patientDetails = PatientData("Surya", 2, "Male", null) -// viewModel.calculateResults() - viewModel.mapWavelengthToAbsorbance() - - for (each in viewModel.wavelengthToAbsorbance){ - println(each[0].toString() + " -> " + each[1]) - } - } } \ No newline at end of file diff --git a/app/src/test/java/com/example/hpostesting/util/TestCoroutineRule.kt b/app/src/test/java/com/example/hpostesting/util/TestCoroutineRule.kt new file mode 100644 index 0000000..cb20d2c --- /dev/null +++ b/app/src/test/java/com/example/hpostesting/util/TestCoroutineRule.kt @@ -0,0 +1,28 @@ +package com.example.hpostesting.util + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.TestCoroutineScope +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@ExperimentalCoroutinesApi +class TestCoroutineRule : TestWatcher(), TestCoroutineScope by TestCoroutineScope() { + + private val testCoroutineDispatcher = TestCoroutineDispatcher() + + override fun starting(description: Description?) { + super.starting(description) + Dispatchers.setMain(testCoroutineDispatcher) + } + + override fun finished(description: Description?) { + super.finished(description) + Dispatchers.resetMain() + cleanupTestCoroutines() + } +} \ No newline at end of file From 60fbd70f2dcb9624409d735ed6b5b9dabb1eab2a Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Fri, 17 Nov 2023 18:20:33 +0530 Subject: [PATCH 13/13] correct strings msg --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 629018b..0d6d018 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -185,8 +185,8 @@ Aadhar ID Internet not available, please enter the user ID and blood group manually User ID should be 18 digits and please select the blood group - Upload DB Registration - Do you want to upload the local DB Registration to the cloud? + Upload DB Tests + Do you want to upload the local DB tests to the cloud? Upload Cancel Upload done successfully