Optimized HemoCube data parsing and changed user card

This commit is contained in:
mohamedkaif356
2023-08-07 17:43:24 +05:30
parent 85d9c6306d
commit 2bb87c7780
4 changed files with 242 additions and 260 deletions

View File

@@ -34,8 +34,8 @@ class UserListAdapter(
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
holder.binding.apply {
userName.text = model.name
userId.text = model._id
userName.text = "Name: ${model.name}"
userId.text = "User ID:${model._id}"
Glide.with(view).load(model.userImageURL).into(userImage)
if (model.testStatus!!) {
teststatus.text = "Test concluded"

View File

@@ -26,124 +26,114 @@ import kotlin.math.log10
class HemoCubeFragment : Fragment() {
private var testTime: String? = null
private var resultRatio: String? = ""
private var resultData: String = ""
private var kitSerial: String? = null
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreference: SharedPreferences
private lateinit var sharedPreferences: SharedPreferences
private var isOnline = false
private var deviceData: DeviceData? = null
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
checkAndStartProcess()
}
if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
private fun initViews() {
binding.btnSubmit.setOnClickListener {
it.isEnabled = false
binding.progressBar.visibility = View.VISIBLE
fetchResult()
}
setupButtonClickListeners()
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
binding.btnBuffer.setOnClickListener { startBufferProcess() }
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") {
Toast.makeText(
requireContext(), "Test Results Uploaded Successfully", Toast.LENGTH_SHORT
).show()
binding.btnKit.setOnClickListener {
resetKitCount()
val intent = Intent(context, KitScanActivity::class.java)
startActivity(intent)
}
}
private fun observeViewModel() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Test Results Uploaded Successfully")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
binding.progressBar.visibility = View.GONE
}
hemoCubeViewModel.getDeviceData(
sharedPreference.getString(Constants.USER_ID, "").toString()
)
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
deviceData = it
Toast.makeText(requireContext(), calculateRatio(0.17).toString(), Toast.LENGTH_SHORT)
.show()
currentDeviceData = it
showToast(calculateRatio(0.17).toString())
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
kitSerial = DataHolder.hemoCubeTestData?.kitSerial
testTime = DataHolder.hemoCubeTestData?.testTime
DataHolder.hemoCubeTestData?.let {
currentDeviceData?.coefficients?.let { coefficients ->
val coefficient1 = coefficients[0]
val coefficient2 = coefficients[1]
val result = coefficient1 * coefficient2
showToast("Result: $result")
}
}
isOnline = isNetworkAvailable
}
}
}
if (checkBufferValue()) {
UIUtils.createAlertDialog(requireContext(),
"WARNING",
"Do you want to continue with existing buffer",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {
listenToHemoCube()
startBuffer()
}
override fun onClickPositiveButton() {
listenToHemoCube()
startSample()
}
})
private fun checkAndStartProcess() {
if (isBufferValueAvailable()) {
showBufferAlertDialog()
} else {
listenToHemoCube()
startBuffer()
startBufferProcess()
}
}
private fun checkBufferValue(): Boolean {
return if (sharedPreference.getString(
Constants.BUFFER_VALUE_1,
""
) != "" && sharedPreference.getString(Constants.BUFFER_VALUE_2, "") != ""
) {
sharedPreference.getString(Constants.BUFFER_VALUE_1, "")
?.toDouble()!! > 0.0 && sharedPreference.getString(Constants.BUFFER_VALUE_2, "")
?.toDouble()!! > 0.0
} else {
false
}
private fun isBufferValueAvailable(): Boolean {
val buffer1 = sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDouble() ?: 0.0
val buffer2 = sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDouble() ?: 0.0
return buffer1 > 0.0 && buffer2 > 0.0
}
private fun setupButtonClickListeners() {
binding.btnSubmit.setOnClickListener {
binding.progressBar.visibility = View.VISIBLE
getResult()
}
private fun showBufferAlertDialog() {
val title = "WARNING"
val message = "Do you want to continue with existing buffer?"
val negativeText = getString(R.string.no)
val positiveText = "Yes"
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
binding.btnBuffer.setOnClickListener {
startBuffer()
}
binding.btnKit.setOnClickListener {
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, 0)
apply()
}
val i = Intent(context, KitScanActivity::class.java)
startActivity(i)
}
UIUtils.createAlertDialog(requireContext(),
title,
message,
negativeText,
positiveText,
object : MyDialogListener {
override fun onClickNegativeButton() {
listenToHemoCube()
startBufferProcess()
}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
private fun listenToHemoCube() {
@@ -159,172 +149,7 @@ class HemoCubeFragment : Fragment() {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
if (stringData.contains("#")) {
binding.tvSubtitle4.text = stringData
}
if (stringData.contains("ERROR 500")) {
UIUtils.createAlertDialog(requireContext(),
"BUFFER ERROR",
"Do you want to continue with existing buffer",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {
}
override fun onClickPositiveButton() {
listenToHemoCube()
startBuffer()
}
})
}
if (stringData.contains("ERROR 501")) {
UIUtils.createAlertDialog(requireContext(),
"SAMPLE ERROR",
"Do you want to continue with Sample",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {
}
override fun onClickPositiveButton() {
listenToHemoCube()
startSample()
}
})
}
resultData += fullReadOutput.toString()
DataHolder.hemoCubeTestData?.resultData
if (stringData.contains("#Buffer Completed")) {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Start Sample",
"Do you want to start sample reading",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSample()
}
})
}
}
if (stringData.contains("#Sample Completed")) {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
}
hemoCubeViewModel.progressBar.postValue(false)
if (stringData.contains("RESULT") || resultData.contains("REND")) {
// DEVICE RESPONSE FORMAT: RESULT SN <DEVICE_SERIAL_NUMBER> <GREEN_BUFFER_INTENSITY> <BLUE_BUFFER_INTENSITY> <GREEN_SAMPLE_INTENSITY> <BLUE_SAMPLE_INTENSITY> REND
// // For example, "RESULT SN 18291 1937.23 2828.11 28211.20 121829.12 REND"
var validString: String
val results: List<String>
if (stringData.contains("RESULT")) {
validString = isValidResult(stringData)
if (validString.isEmpty()) {
results = resultData.split("\n")
validString = parseResult(results)
}
} else {
results = resultData.split("\n")
validString = parseResult(results)
}
if (validString.isNotEmpty()) {
val result = validString.split(" ")
if (result.size == 8) {
val deviceSerialNo = result[2]
val led1Buffer = result[3].toDoubleOrNull()
val led2Buffer = result[4].toDoubleOrNull()
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1Buffer?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2Buffer?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
DataHolder.hemoCubeTestData?.deviceSerialNumber = deviceSerialNo
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
if (kitCount < 35 && sharedPreference.getString(
Constants.BUFFER_VALUE_1, ""
).isNullOrEmpty()
) DataHolder.hemoCubeTestData?.led1Buffer = led1Buffer
else DataHolder.hemoCubeTestData?.led1Buffer =
sharedPreference.getString(Constants.BUFFER_VALUE_1, "")
?.toDoubleOrNull()
if (kitCount < 35 && sharedPreference.getString(
Constants.BUFFER_VALUE_2, ""
).isNullOrEmpty()
) DataHolder.hemoCubeTestData?.led2Buffer = led2Buffer
else DataHolder.hemoCubeTestData?.led2Buffer =
sharedPreference.getString(Constants.BUFFER_VALUE_2, "")
?.toDoubleOrNull()
DataHolder.hemoCubeTestData?.led1Sample = led1Sample
DataHolder.hemoCubeTestData?.led2Sample = led2Sample
DataHolder.hemoCubeTestData?.led1Average = led1Average
DataHolder.hemoCubeTestData?.led2Average = led2Average
DataHolder.hemoCubeTestData?.deviceRatio = deviceRatio
DataHolder.hemoCubeTestData?.calculatedRatio =
calculateRatio(deviceRatio)
DataHolder.hemoCubeTestData?.resultData = resultData
resultRatio = deviceRatio.toString()
if (!checkBufferValue()) {
with(sharedPreference.edit()) {
putString(Constants.BUFFER_VALUE_1, led1Buffer.toString())
putString(Constants.BUFFER_VALUE_2, led2Buffer.toString())
apply()
}
}
// TODO: merge
if (isOnline) {
resultRatio?.let { ratio ->
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, kitSerial
)
}
binding.progressBar.visibility = View.VISIBLE
} else {
resultRatio?.let { ratio ->
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, kitSerial
)
}
Toast.makeText(
requireContext(),
"Internet not available, Test Data added to Local DB.",
Toast.LENGTH_SHORT
).show()
}
}
}
}
handleUsbData(stringData, fullReadOutput)
}
}
@@ -334,38 +159,185 @@ class HemoCubeFragment : Fragment() {
})
}
private fun startBuffer() {
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
if (stringData.contains("#")) {
binding.tvSubtitle4.text = stringData
}
resultData += fullReadOutput.toString()
when {
stringData.contains("ERROR 500") -> showError500Dialog()
stringData.contains("ERROR 501") -> showError501Dialog()
stringData.contains("#Buffer Completed") -> showStartSampleDialog()
stringData.contains("#Sample Completed") -> {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
}
stringData.contains("RESULT") || resultData.contains("REND") -> {
var validString = ""
val results: List<String>
if (stringData.contains("RESULT")) {
validString = isValidResult(stringData)
if (validString.isEmpty()) {
results = resultData.split("\n")
validString = parseResult(results)
}
} else {
results = resultData.split("\n")
validString = parseResult(results)
}
if (validString.isNotEmpty()) {
handleValidResult(validString, resultData)
}
}
}
}
private fun showError500Dialog() {
UIUtils.createAlertDialog(requireContext(),
"BUFFER ERROR",
"Do you want to continue with existing buffer?",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startBufferProcess()
}
})
}
private fun showError501Dialog() {
UIUtils.createAlertDialog(requireContext(),
"SAMPLE ERROR",
"Do you want to continue with Sample?",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
private fun showStartSampleDialog() {
UIUtils.createAlertDialog(requireContext(),
"Start Sample",
"Do you want to start sample reading?",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
private fun handleValidResult(validString: String, fullReadOutput: String) {
val result = validString.split(" ")
if (result.size == 8) {
val deviceSerialNo = result[2]
var led1Buffer = result[3].toDoubleOrNull()
var led2Buffer = result[4].toDoubleOrNull()
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1Buffer?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2Buffer?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
DataHolder.hemoCubeTestData?.apply {
deviceSerialNumber = deviceSerialNo
led1Buffer = if (sharedPreferences.getInt(
Constants.KIT_COUNT, 0
) < 35 && sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")
.isNullOrEmpty()
) {
led1Buffer
} else {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()
}
led2Buffer = if (sharedPreferences.getInt(
Constants.KIT_COUNT, 0
) < 35 && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")
.isNullOrEmpty()
) {
led2Buffer
} else {
sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull()
}
this.led1Sample = led1Sample
this.led2Sample = led2Sample
this.led1Average = led1Average
this.led2Average = led2Average
this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio)
this.resultData = fullReadOutput
if (!isBufferValueAvailable()) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1Buffer.toString())
putString(Constants.BUFFER_VALUE_2, led2Buffer.toString())
apply()
}
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
}
}
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
private fun startBufferProcess() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.startBuffer,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun startSample() {
private fun startSampleProcess() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.startSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun getResult() {
private fun fetchResult() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.getSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
@@ -373,9 +345,9 @@ class HemoCubeFragment : Fragment() {
}
private fun calculateRatio(ratio: Double): Double {
val c1 = deviceData?.coefficients?.get(0)!!
val c2 = deviceData?.coefficients?.get(1)!!
return c1 * ratio + c2
val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
return coefficient1 * ratio + coefficient2
}
private fun parseResult(frames: List<String>): String {
@@ -394,9 +366,17 @@ class HemoCubeFragment : Fragment() {
}
private fun isValidResult(line: String): String {
if (line.contains("RESULT") && line.split(" ").size == 8) {
return line
return if (line.contains("RESULT") && line.split(" ").size == 8) {
line
} else {
""
}
}
private fun resetKitCount() {
with(sharedPreferences.edit()) {
putInt(Constants.KIT_COUNT, 0)
apply()
}
return ""
}
}

View File

@@ -56,9 +56,11 @@ class HemocubeActivity : AppCompatActivity() {
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
connectUsb(true)
DataHolder.usbConnected.postValue(true)
}
} else {
onErrorReported("permission denied for device")
DataHolder.usbConnected.postValue(true)
}
}

View File

@@ -36,7 +36,7 @@
android:layout_marginStart="16dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="16sp"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toTopOf="@+id/userImage"
@@ -48,10 +48,10 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="16sp"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userName"
@@ -62,11 +62,11 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/title1_1"
android:layout_marginTop="8dp"
android:layout_marginTop="4dp"
android:layout_marginStart="16dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="16sp"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userId"