device Diagnostics for user has been integrated

This commit is contained in:
chandrashekhar reddy
2024-04-29 18:15:20 +05:30
parent 0b6e3749c3
commit 4ba2f38583
6 changed files with 203 additions and 32 deletions

View File

@@ -168,5 +168,6 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation 'io.nats:jnats:2.11.4'
implementation 'org.apache.commons:commons-math3:3.6.1'
}

View File

@@ -145,6 +145,7 @@ class DatabaseRepository @Inject constructor(
}
}
override suspend fun addTestJigData(data: JigData?): Response<String> {
return try {
db.collection("jigs").add(data!!).await()

View File

@@ -90,7 +90,7 @@ class GalleryFragment : Fragment() {
binding.btnDeviceProvision.visibility = View.GONE
binding.btnAutoDac.visibility = View.GONE
binding.btnDeviceProvision.visibility = View.GONE
binding.btnDiagnostics.visibility = View.GONE
binding.btnDiagnostics.visibility = View.VISIBLE
binding.btnFiles.visibility = View.GONE
binding.btnFirefox.visibility = View.GONE
binding.btnCalibration.visibility = View.GONE

View File

@@ -375,7 +375,7 @@ class HomeFragment : Fragment() {
}
} else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) {
fetchDeviceCredentials()
} else if (file.exists()) {
} else if (!file.exists()) {
val encryptedString = file.readText()
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)

View File

@@ -18,6 +18,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -26,30 +27,39 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.autodac.AutoDacActivity
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding
import org.apache.commons.math3.stat.regression.SimpleRegression
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
class DiagnosticsFragment : Fragment() {
class DiagnosticsFragment : Fragment() {
// Initialize variables to store LED DAC values
var led1Dac: Int? = null
var led2Dac: Int? = null
var led3Dac: Int? = null
var led4Dac: Int? = null
private var testStatusCode = 0.0
private lateinit var binding: FragmentDiagnosticsBinding
private val diagnosticsViewModel: DiagnosticsViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private val messages = MutableLiveData<String>()
private var currentResultData: String = ""
private var startListening = MutableLiveData(false)
private val batteryStatus: Intent? =
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
@@ -73,9 +83,12 @@ class DiagnosticsFragment : Fragment() {
private fun initViews() {
binding.btnSubmit.visibility = View.GONE
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
listenToHemoCube()
getDeviceId()
binding.btnSubmit.setOnClickListener {
diagnosticsViewModel.messages.postValue("Processing Diagnostics...")
binding.btnSubmit.visibility = View.GONE
runDeviceDiagnostics()
val batteryLevel = "" //diagnosticsViewModel.getBatteryLevel().toString()
@@ -97,8 +110,6 @@ class DiagnosticsFragment : Fragment() {
)
}
}
}
@@ -108,7 +119,7 @@ class DiagnosticsFragment : Fragment() {
currentDeviceData = it
}
messages.observe(viewLifecycleOwner) {
diagnosticsViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
Log.e("diagnostics", binding.tvSubtitle4.text.toString())
}
@@ -155,6 +166,8 @@ class DiagnosticsFragment : Fragment() {
}
is Result.Loading -> {
}
else -> {}
}
}
@@ -167,11 +180,11 @@ class DiagnosticsFragment : Fragment() {
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
// data?.let {
// val stringData = String(it)
// diagnosticsViewModel.messages.postValue(stringData)
// binding.tvSubtitle4.text = stringData
// }
}
override fun onUsbError(e: Exception?) {
@@ -193,10 +206,22 @@ class DiagnosticsFragment : Fragment() {
}
})
}
private fun readCurrentDACValuesCommand() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.READ_DAC_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
}
private fun listenToHemoCube() {
diagnosticsViewModel.messages.postValue("Place cuvette filled with buffer\n and click on start")
val fullReadOutput = StringBuilder()
startListening.postValue(true)
@@ -206,23 +231,24 @@ class DiagnosticsFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData)
fullReadOutput.append(stringData)
resultData += stringData
binding.tvSubtitle4.text = resultData
if (stringData.contains("SN")) {
val slData = stringData.split(" ")
if (slData.size > 1) {
val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId)
apply()
}
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
}
}
handleUsbData(stringData)
// binding.tvSubtitle4.text = resultData
// if (stringData.contains("SN")) {
// val slData = stringData.split(" ")
// if (slData.size > 1) {
// val hardwareId = slData[1].trim()
// with(sharedPreferences.edit()) {
// putString(Constants.DEVICE_ID, hardwareId)
// apply()
// }
// }
// activity?.runOnUiThread {
// binding.btnSubmit.visibility = View.VISIBLE
// }
// }
}
if (resultData.contains("END") || fullReadOutput.contains("END")) {
@@ -270,6 +296,148 @@ class DiagnosticsFragment : Fragment() {
}
}
private fun handleUsbData(stringData: String) {
resultData += stringData
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
currentResultData += stringData
}
when {
(resultData.contains("SNE") && this.testStatusCode < 1.0) -> {
this.testStatusCode = 1.1
val slData = stringData.split(" ")
if (slData.size > 1) {
val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId)
apply()
}
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
}
}
(resultData.contains("#DC") && this.testStatusCode < 1.4) -> {
this.testStatusCode = 1.5
activity?.runOnUiThread {
readCurrentDACValuesCommand()
}
}
(resultData.contains("#RC") && this.testStatusCode < 1.6) -> {
this.testStatusCode = 1.7
activity?.runOnUiThread {
finalCalculation()
}
}
}
}
private fun finalCalculation() {
val pattern = Regex("(LED:\\d+)__DAC:(\\d+)__ADC:(\\d+)")
// Find all matches in the string
val matches = pattern.findAll(resultData)
// Initialize lists for x and y values for each LED
val ledDataMap = mutableMapOf<String, MutableList<Pair<Double, Double>>>()
// Extract LED name, x, and y values from each match and add to the corresponding lists
for (match in matches) {
val ledName = match.groupValues[1]
val xValue = match.groupValues[2].toDouble()
val yValue = match.groupValues[3].toDouble()
// Add x and y values to the corresponding lists based on the LED name
if (!ledDataMap.containsKey(ledName)) {
ledDataMap[ledName] = mutableListOf()
}
if ((ledDataMap[ledName]?.size ?: 0) < 6) {
ledDataMap[ledName]?.add(xValue to yValue)
}
// ledDataMap[ledName]?.add(xValue to yValue)
}
// String array to store pass or fail messages for each LED
val results = mutableListOf<String>()
// Print the extracted x and y values for each LED
// Regular expression to match LED DAC values
val regex = Regex("LED(\\d) DAC : (\\d+)")
// Find LED DAC values using regex
regex.findAll(resultData).forEach {
val (led, dac) = it.destructured
val dacValue = dac.toInt()
when (led.toInt()) {
1 -> led1Dac = dacValue
2 -> led2Dac = dacValue
3 -> led3Dac = dacValue
4 -> led4Dac = dacValue
}
}
println("$led1Dac")
println("LED2 DAC: $led2Dac")
println("LED3 DAC: $led3Dac")
println("LED4 DAC: $led4Dac")
for ((ledName, data) in ledDataMap) {
// println("$ledName x-values: ${data.map { it.first }}")
// println("$ledName y-values: ${data.map { it.second }}")
val message = calculateRegressionAndDAC(ledName, data)
results.add(message)
}
// Print the pass or fail messages for each LED
results.forEach {
currentResultData += it
diagnosticsViewModel.messages.postValue(currentResultData)
println(it)
}
}
private fun calculateRegressionAndDAC(ledName: String, data: List<Pair<Double, Double>>): String {
val regression = SimpleRegression()
data.forEach { (x, y) -> regression.addData(x, y) }
val slope = regression.slope
val constant = regression.intercept
val rSquared = regression.rSquare
// Check R-squared value and generate pass or fail message
val message = if (rSquared > 0.98) {
"$ledName linearity PASS (✓)\n"
} else {
"$ledName linearity FAIL (✗)\n"
}
// Calculation for ADC value
val adcValue = when (ledName) {
"LED:1" -> 22000.0
"LED:2", "LED:3" -> 18000.0
"LED:4" -> 22000.0
else -> 0.0
}
val dacValue = calculateDAC(adcValue, slope, constant)
val resultDAC = dacValue - led1Dac!!
if(resultDAC < 200){
currentResultData += "$ledName DAC LEVEL PASS (✓)\n"
println("$ledName DAC LEVEL PASS")
}else{
currentResultData += "$ledName DAC LEVEL FAIL (✗)\n"
println("$ledName DAC LEVEL FAIL")
}
return message
}
fun calculateDAC(adc: Double, slope: Double, constant: Double): Double {
return (adc - constant) / slope
}
fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)")
val parsedData = mutableListOf<Pair<String, String>>()

View File

@@ -59,11 +59,12 @@
android:id="@+id/tv_subtitle4"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="380dp"
android:layout_height="450dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="Start"
android:scrollbars="vertical"
android:textColor="@color/red"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"