HemoCube new Changes

This commit is contained in:
smileomi18@gmail.com
2023-07-27 16:44:12 +05:30
parent a5db2e759c
commit 97b66acda3
9 changed files with 79 additions and 165 deletions

View File

@@ -35,7 +35,9 @@
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
android:exported="false"
android:noHistory="true"
android:theme="@style/Theme.HPOS.NoActionBar" />
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="com.example.hpostesting.presentation.KitScanActivity"
android:exported="false"

View File

@@ -1,20 +1,31 @@
package com.example.hpostesting.presentation.hemocube
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.ViewModel;
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.bumptech.glide.load.model.stream.HttpGlideUrlLoader.TIMEOUT
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants.ACTION_USB_PERMISSION
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
class HemoCubeFragment : Fragment() {
@@ -26,6 +37,15 @@ class HemoCubeFragment : Fragment() {
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreference: SharedPreferences
private var isOnline = false
private val ACTION_USB_PERMISSION = "com.example.usbpermission"
private val TIMEOUT = 0
private val usbManager: UsbManager by lazy {
requireContext().getSystemService(Context.USB_SERVICE) as UsbManager
}
private var usbDevice: UsbDevice? = null
private var usbConnection: UsbDeviceConnection? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -52,7 +72,7 @@ class HemoCubeFragment : Fragment() {
binding.progressBar.visibility = View.GONE
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
kitSerial = DataHolder.SelectTestType?.kitSerial
testTime = DataHolder.SelectTestType?.testTime
@@ -63,6 +83,7 @@ class HemoCubeFragment : Fragment() {
private fun setupButtonClickListeners() {
binding.btnShowResult.setOnClickListener {
// readUsbData()
fetchHemoCubeResult()
}
@@ -107,6 +128,56 @@ class HemoCubeFragment : Fragment() {
}
}
private fun readUsbData() {
// Perform USB data reading and parsing here
val buffer = ByteArray(256) // Adjust the buffer size as per your data
val endpoint = usbDevice?.getInterface(0)?.getEndpoint(0)
endpoint?.let {
val bytesRead = usbConnection?.bulkTransfer(it, buffer, buffer.size, TIMEOUT)
if (bytesRead != null && bytesRead > 0) {
val usbData = String(buffer, 0, bytesRead, Charsets.UTF_8)
val parsedData = parseUsbData(usbData)
displayValuesOnTextView(parsedData)
} else {
// Handle USB data read error
}
}
}
private fun parseUsbData(data: String): Map<String, String> {
val lines = data.split("\n")
val parsedData = mutableMapOf<String, String>()
for (line in lines) {
val labelAndValue = line.split(":")
if (labelAndValue.size == 2) {
val label = labelAndValue[0].trim()
val value = labelAndValue[1].trim()
parsedData[label] = value
}
}
return parsedData
}
private fun displayValuesOnTextView(parsedData: Map<String, String>) {
val fullReadOutput = StringBuilder()
val textView: TextView = requireView().findViewById(R.id.tv_subtitle4)
val resultText = buildString {
for ((label, value) in parsedData) {
append("$label: $value\n")
}
}
// Display the complete data accumulated so far
fullReadOutput.append(resultText)
textView.text = fullReadOutput.toString()
}
private fun fetchHemoCubeResult() {
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
@@ -118,6 +189,8 @@ class HemoCubeFragment : Fragment() {
fullReadOutput.append(stringData)
binding.tvSubtitle4.text = fullReadOutput
resultRatio = fullReadOutput.toString()
val data = parseUsbData(fullReadOutput.toString())
Log.d("Result", data.toString())
hemoCubeViewModel.progressBar.postValue(false)
}
}

View File

@@ -103,17 +103,6 @@ class TestRightActivity : AppCompatActivity() {
}
}
// private fun testing() {
// supportFragmentManager.beginTransaction()
// .replace(binding.flMain.id, TestRightExpSample()).commit()
// }
// Todo: Comment this
// private fun connectUsb(permissionGranted: Boolean) {
// setupService()
// }
// Todo: Uncomment this
private fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -124,13 +113,6 @@ class TestRightActivity : AppCompatActivity() {
} else {
mDriver = availableDrivers[0]
// if (mDriver.device.productId != Constants.DEVICE_PRODUCT_ID || mDriver.device.vendorId != Constants.DEVICE_VENDOR_ID
// || (mDriver.device.productId != Constants.HOMO_CUBE_ID || mDriver.device.vendorId != Constants.VENDOR_ID)){
// Toast.makeText(this, "Device Connected is not supported", Toast.LENGTH_SHORT).show()
// onBackPressed()
// return
// }
viewModel.testDetails?.deviceId = mDriver.device.serialNumber.toString()
DataHolder.deviceSerialNumber = mDriver.device.serialNumber.toString()
mConnection = manager.openDevice(mDriver.device)
@@ -143,12 +125,7 @@ class TestRightActivity : AppCompatActivity() {
}
}
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
// Log.d(TAG, "requestUserPermissions() called -> vendor id = ${device.vendorId} & product id = ${device.productId}")
val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast(
@@ -197,11 +174,6 @@ class TestRightActivity : AppCompatActivity() {
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
// Snackbar.make(binding.clParent, msg, Snackbar.LENGTH_LONG)
// .setAction("CLOSE") { Toast.makeText(this, "Will soon", Toast.LENGTH_SHORT).show() }
// .setActionTextColor(resources.getColor(R.color.white))
// .show()
if (!isFinishing)
onBackPressed()
}
@@ -211,16 +183,6 @@ class TestRightActivity : AppCompatActivity() {
myMenu = menu
return true
}
// override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
// R.id.action_usb -> {
//// Toast.makeText(this, "USB Connected", Toast.LENGTH_SHORT).show()
//// myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
// true
// }
// else -> {super.onOptionsItemSelected(item)}
// }
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {
@@ -229,10 +191,4 @@ class TestRightActivity : AppCompatActivity() {
viewModel.isServiceConnected = false
}
}
// fun View.setAllEnabled(enabled: Boolean) {
// isEnabled = enabled
// if (this is ViewGroup) children.forEach { child -> child.setAllEnabled(enabled) }
// }
}

View File

@@ -24,16 +24,12 @@ import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceB
@AndroidEntryPoint
class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding
private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightExpReference"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false)
return binding.root
}
@@ -41,12 +37,6 @@ class TestRightExpReference : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
// if (DataHolder.isReferenceTaken)
// moveToSamplePage()
//
// DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
if (DataHolder.deviceConstant == null) {
viewModel.progressBar.postValue(true)
Handler(Looper.getMainLooper()).postDelayed(
@@ -83,7 +73,6 @@ class TestRightExpReference : Fragment() {
}
viewModel.progressBar.observe(viewLifecycleOwner) {
// Log.d(TAG, "SURYA OBSERVER Activated outcome = $it")
if (it) {
binding.progressBar.visibility = View.VISIBLE
binding.clParent.alpha = 0.5f
@@ -107,9 +96,6 @@ class TestRightExpReference : Fragment() {
private fun startTakingReference() {
sendCmdToSetLed()
}
// private fun sendCmdToFetchDeviceConstant(recursive: Boolean) {
private fun sendCmdToFetchDeviceConstant() {
Log.d(TAG, "sendCmdToFetchDeviceConstant() called")
@@ -244,7 +230,6 @@ class TestRightExpReference : Fragment() {
)
}
}
// }
}
override fun onUsbError(e: Exception?) {
@@ -266,10 +251,6 @@ class TestRightExpReference : Fragment() {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
// Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (stringData.trim().isNotEmpty() && fullReadOutput.substring(
Math.max(
fullReadOutput.length - 15, 0
@@ -278,11 +259,7 @@ class TestRightExpReference : Fragment() {
) {
Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()")
// Log.d(TAG, fullReadOutput.toString())
viewModel.mapIntensityValues(fullReadOutput.toString(), true)
// viewModel.saveLogTest(requireContext().applicationContext, true, fullReadOutput.toString())
DataHolder.isReferenceTaken = true
Handler(Looper.getMainLooper()).postDelayed(

View File

@@ -35,16 +35,7 @@ class TestRightExpSample : Fragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpSampleBinding.inflate(inflater, container, false)
// if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) {
// binding.btnUpdateReference.enable()
// binding.clInstructions.setAllEnabled(false)
// } else {
// binding.btnUpdateReference.disable()
// binding.clInstructions.setAllEnabled(false)
// }
return binding.root
}
@@ -75,10 +66,6 @@ class TestRightExpSample : Fragment() {
}
binding.btnSubmit.setOnClickListener {
// val details = validateAndReturnTestData()
// if (details != null) {
// viewModel.patientDetails = details
UIUtils.createAlertDialog(
requireContext(),
"WARNING",
@@ -111,24 +98,13 @@ class TestRightExpSample : Fragment() {
val i = Intent(requireContext(), MainActivity::class.java)
startActivity(i)
}
// binding.etNameBlock.setOnClickListener { binding.etName.isErrorEnabled = false }
// binding.etAgeBlock.setOnClickListener { binding.etAge.isErrorEnabled = false }
// binding.etGenderBlock.setOnClickListener { binding.ddGender.isErrorEnabled = false }
}
// private fun validateAndReturnTestData(): TestDetails? {
//
// return PatientData(name.toString(), age.toString().toInt(), gender.toString(), TestRightResultType.UNDEFINED)
// }
/**
* Executing the commands sequentially each after successfully executing one.
* 1. command run
* 2. command print
*/
private fun startAcquiring() {
// binding.progressBar.visibility = View.VISIBLE
sendCmdToRun()
}
@@ -144,9 +120,6 @@ class TestRightExpSample : Fragment() {
val stringData = String(it)
fullReadOutput.append(stringData)
Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) {
// if (stringData.contains("OK", true) || fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) {
Log.d(TAG, "onUsbRead() called in sendCmdToRun()")
Handler(Looper.getMainLooper()).postDelayed(
@@ -183,17 +156,10 @@ class TestRightExpSample : Fragment() {
val stringData = String(it)
fullReadOutput.append(stringData)
Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) {
// if (stringData.contains("OK", true) || stringData.contains("O", true) || stringData.contains("K", true)) {
// if (stringData.contains("OK", true) || fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (stringData.trim().isNotEmpty() && fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) {
Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()")
viewModel.mapIntensityValues(fullReadOutput.toString(), false)
// viewModel.saveLogTest(requireContext().applicationContext, false, fullReadOutput.toString())
// showResultsAfterAcquiring()
Handler(Looper.getMainLooper()).postDelayed(
{
checkIfToRunAgain()
@@ -219,15 +185,11 @@ class TestRightExpSample : Fragment() {
viewModel.mapWavelengthToAbsorbance()
// Todo: Save CSV + Test CSV
if (DataHolder.selectedTestType == TestType.SICKLECERT) {
viewModel.calculateResults()
} else {
viewModel.calculateResultsForSickleFind()
}
// Todo: Save Log
saveDataLocally()
if (viewModel.numberOfSampleRun < Constants.NO_OF_TIMES_TO_RUN_SAMPLE) {
@@ -244,33 +206,13 @@ class TestRightExpSample : Fragment() {
}
private fun showResultsAfterAcquiring() {
// viewModel.mapWavelengthToAbsorbance()
// viewModel.calculateResults()
viewModel.progressBar.postValue(false)
// binding.progressBar.visibility = View.GONE
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightResults())
.commit()
}
private fun saveDataLocally() {
// OLD ------------------------------
// val patientName = viewModel.testDetails?.patientName
// if (patientName.length > 5){
// patientName = patientName.substring(0, 5)
// }
// val id = PreferenceUtility.generateId(requireContext())
// val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT)
// "HPOSSC_${DataHolder.deviceSerialNumber}_${patientName}_"
// else
// "HPOSSF_${DataHolder.deviceSerialNumber}_${patientName}_"
// val fileNameCsv = prefixCsv + id + fileExtensionCsv
// NEW ------------------------------
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
// viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName())
}

View File

@@ -38,7 +38,6 @@ class TestRightResults : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
@@ -115,36 +114,6 @@ class TestRightResults : Fragment() {
if (DataHolder.selectedTestType == TestType.SICKLECERT) {
// when (viewModel.testDetails?.result) {
// TestRightResultType.NORMAL -> {
// binding.resultNormal.visibility = View.VISIBLE
// }
//
// TestRightResultType.SICKLECELLDISEASE -> {
// binding.resultDisease.visibility = View.VISIBLE
// }
//
// TestRightResultType.SICKLECELLTRAIT -> {
// binding.resultTrait.visibility = View.VISIBLE
// }
//
// TestRightResultType.POSITIVEBORDERLINE -> {
// binding.resultPositiveBorderline.visibility = View.VISIBLE
// binding.tvRecommended.visibility = View.VISIBLE
// }
//
// TestRightResultType.NEGATIVEBORDERLINE -> {
// binding.resultNegativeBorderline.visibility = View.VISIBLE
// binding.tvRecommended.visibility = View.VISIBLE
// }
// else -> {
//// binding.resultUndefined.visibility = View.VISIBLE
// Toast.makeText(
// requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
// ).show()
// moveToSamplePage()
// }
// }
binding.resultNormal.visibility = View.VISIBLE
} else {
when (viewModel.testDetails?.result) {
@@ -194,6 +163,4 @@ class TestRightResults : Fragment() {
.commit()
}
}
}

View File

@@ -64,8 +64,6 @@ class TestRightViewModel @Inject constructor(
val allUserData = userDao.getAll()
private lateinit var calculationData: TestRightCalculationData
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
val intensitySampleArray = ArrayList<Double>()
val wavelengthToAbsorbance = ArrayList<ArrayList<Double>>()
@@ -73,8 +71,6 @@ class TestRightViewModel @Inject constructor(
val calculationVariableList = ArrayList<CalculationVariableForTest>()
fun mapDeviceConstants(string: String) {
// Log.d(TAG, "mapDeviceConstants() called")
// Log.d(TAG, "mapDeviceConstants() value -> $string")
if (string.isNotEmpty()) {
val listOfStrings = string.split(",")
if (listOfStrings.size >= 4) {

View File

@@ -51,7 +51,7 @@
android:id="@+id/tv_subtitle4"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:hint="Result"

View File

@@ -10,6 +10,7 @@
<!-- <usb-device vendor-id="1027" product-id="24593" /> &lt;!&ndash; 0x6011: FT4232H &ndash;&gt;-->
<!-- <usb-device vendor-id="1027" product-id="24596" /> &lt;!&ndash; 0x6014: FT232H &ndash;&gt;-->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<!-- 0x10C4 / 0xEA??: Silabs CP210x -->
<!-- <usb-device vendor-id="4292" product-id="60000" /> &lt;!&ndash; 0xea60: CP2102 and other CP210x single port devices &ndash;&gt;-->