From c5c0467e421cf098891d440ce1174a6f4ad47f2d Mon Sep 17 00:00:00 2001 From: Mariya Date: Thu, 8 Feb 2024 11:48:35 +0530 Subject: [PATCH 1/8] code added to store device provision response --- app/src/main/AndroidManifest.xml | 7 +- .../data/model/patient/DeviceData.kt | 6 +- .../data/repository/DatabaseRepository.kt | 10 ++ .../hpostesting/data/repository/Repository.kt | 1 + .../deviceinfo/DeviceViewModel.kt | 3 +- .../DeviceProvisionFragment.kt | 135 +++++++++++------- .../DeviceProvisionViewModel.kt | 40 +++++- 7 files changed, 142 insertions(+), 60 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8b755b0..c4d08b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -118,11 +118,8 @@ android:noHistory="true" android:theme="@style/AppTheme.NoActionBar"> - - - - - + + = emptyList(), @get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt") - var calibratedAt: String = "" + var calibratedAt: String = "" , + @get:PropertyName("deviceProvisionResponse") @set:PropertyName("deviceProvisionResponse") + var deviceProvisionResponse: String = "" + ) \ No newline at end of file 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 bffe71e..0812cd6 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 @@ -203,6 +203,16 @@ class DatabaseRepository @Inject constructor( return allDeviceDataList.find { it.deviceId == deviceId } } + + override suspend fun getDeviceResponse(data: DeviceData): Response? { + return try { + db.collection("devices").add(data!!).await() + Response.Success(data.deviceProvisionResponse) + } catch (e: Exception) { + Firebase.crashlytics.recordException(e) + Response.Error(e) + } + } override fun addTestToDatabase(testDetails: UserData): Any { TODO("Not yet implemented") } 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 cd3e9b5..ecdad95 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 @@ -32,6 +32,7 @@ interface Repository { suspend fun uploadFileToStorage(patientID: String, filePath: String): Response suspend fun getDeviceDataById(deviceId: String): DeviceData? + suspend fun getDeviceResponse(data: DeviceData): Response? abstract fun addTestToDatabase(testDetails: UserData): Any // suspend fun addToDatabase(data: PatientDetails) diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt index 4f43ca8..0d2e5d8 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt @@ -20,6 +20,7 @@ class DeviceViewModel @Inject constructor( val deviceData = MutableLiveData() // val networkStatusLiveData: LiveData // get() = _networkStatusLiveData - val fireBaseUpload = MutableLiveData() +val fireBaseUpload = MutableLiveData() + val fireBaseBulkUpload = MutableLiveData() } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index 5ebc428..4a6b6ee 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -10,15 +10,24 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest +import com.example.hpostesting.data.model.diagnostics.DiagnosticsData +import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase +import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale class DeviceProvisionFragment : Fragment() { @@ -26,6 +35,10 @@ class DeviceProvisionFragment : Fragment() { private lateinit var binding: FragmentDeviceProvisionBinding private val viewModel: DeviceProvisionViewModel by activityViewModels() private lateinit var sharedPreferences: SharedPreferences + private lateinit var deviceProvisionResponse: String + private var currentDeviceData: DeviceData? = null + private var isOnline = false + val deviceData = MutableLiveData() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { @@ -53,65 +66,87 @@ class DeviceProvisionFragment : Fragment() { ) ) } - } + + + + + viewModel.deviceData.observe(viewLifecycleOwner) { + currentDeviceData = it + } + + } + private fun observeViewModel() { - viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> - when (response) { - is Result.Success -> { - if (response.data.result == "Success") { - with(sharedPreferences.edit()) { - putString( - Constants.DEVICE_ID_API, - response.data.data?.credentials?.username - ) - putString( - Constants.DEVICE_PASSWORD_API, - response.data.data?.credentials?.password - ) - putString( - Constants.NATS_TOKEN, - response.data.data?.device?.deviceUser?.natsToken - ) - putString( - Constants.NATS_TOKEN_EXPIRE_DATE, - response.data.data?.device?.deviceUser?.natsTokenExpiry - ) - apply() + viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> + when (response) { + is Result.Success -> { + if (response.data.result == "Success") { + with(sharedPreferences.edit()) { + putString( + Constants.DEVICE_ID_API, + response.data.data?.credentials?.username + ) + putString( + Constants.DEVICE_PASSWORD_API, + response.data.data?.credentials?.password + ) + putString( + Constants.NATS_TOKEN, + response.data.data?.device?.deviceUser?.natsToken + ) + putString( + Constants.NATS_TOKEN_EXPIRE_DATE, + response.data.data?.device?.deviceUser?.natsTokenExpiry + ) + apply() + } + startActivity( + Intent( + requireContext(), + DashboardActivity::class.java + ) + ) + Toast.makeText( + activity, "Device registered successfully", Toast.LENGTH_LONG + ).show() + + viewModel.addDeviceProvisionDataToDb( + DeviceData( + deviceProvisionResponse = response.toString() + ) + ) + + } else { + Toast.makeText( + activity, + "An error in device provision: ${response.data.message}", + Toast.LENGTH_LONG + ).show() + binding.btnSubmit.visibility = View.VISIBLE + } + } - startActivity(Intent(requireContext(), DashboardActivity::class.java)) - Toast.makeText( - activity, "Device registered successfully", Toast.LENGTH_LONG - ).show() - } else { - Toast.makeText( - activity, - "An error occurred in device provision: ${response.data.message}", - Toast.LENGTH_LONG - ).show() - binding.btnSubmit.visibility = View.VISIBLE - } - } + is Result.Error -> { + response.exception.let { message -> + Toast.makeText( + activity, + "An error occurred in device provision: $message", + Toast.LENGTH_LONG + ).show() + } + } - is Result.Error -> { - response.exception.let { message -> - Toast.makeText( - activity, - "An error occurred in device provision: $message", - Toast.LENGTH_LONG - ).show() + is Result.Loading -> { + binding.btnSubmit.visibility = View.GONE + } + + else -> {} } } - is Result.Loading -> { - binding.btnSubmit.visibility = View.GONE - } - - else -> {} - } - } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt index b64a2a9..aa0be0c 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt @@ -1,11 +1,17 @@ package com.example.hpostesting.presentation.deviceprovision +import android.content.Context +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.Result +import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse +import com.example.hpostesting.data.model.diagnostics.DiagnosticsData +import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.repository.Repository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -13,17 +19,45 @@ import javax.inject.Inject @HiltViewModel class DeviceProvisionViewModel @Inject constructor( - private val databaseRepository: Repository + private val databaseRepository: Repository, + private val repository: Repository, + context: Context, ) : ViewModel() { + private val _networkStatusLiveData = NetworkStatusLiveData(context) var isServiceConnected = false - + val networkStatusLiveData: LiveData get() = _networkStatusLiveData val deviceProvisionResponse = MutableLiveData>() - + val fireBaseUpload = MutableLiveData() + val fireBaseBulkUpload = MutableLiveData() + val deviceData = MutableLiveData() fun deviceProvision(deviceProvisionRequest: DeviceProvisionRequest) = viewModelScope.launch { deviceProvisionResponse.postValue(Result.Loading()) databaseRepository.deviceProvision(deviceProvisionRequest).let { deviceProvisionResponse.postValue(it) } } + + fun addDeviceProvisionDataToDb(data: DeviceData) { + viewModelScope.launch { + try { + when (val response = repository.getDeviceResponse(data)) { + is Response.Success -> { +// Log.i("Testdb", "Data uploaded to Firestore successfully") + fireBaseUpload.postValue("Success") + } + + is Response.Error -> { +// Log.e("Testdb", "Error uploading data to Firestore: $response") + fireBaseUpload.postValue("Error") + } + + else -> {} + } + } catch (e: Exception) { +// Log.e("Testdb", "Exception during data upload: ${e.message}") + fireBaseUpload.postValue("Error") + } + } + } } \ No newline at end of file From 6ddb491bc89ee4bedfc0a3bdbc72758d6982c32e Mon Sep 17 00:00:00 2001 From: Mariya Date: Thu, 8 Feb 2024 12:18:31 +0530 Subject: [PATCH 2/8] Added code to send response of device provision api into firebase --- .../DeviceProvisionFragment.kt | 142 ++++++++---------- 1 file changed, 63 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index 4a6b6ee..a86fc25 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -10,27 +10,19 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest -import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase -import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding -import java.text.SimpleDateFormat -import java.util.Calendar -import java.util.Locale class DeviceProvisionFragment : Fragment() { - private var resultData: String = "" private lateinit var binding: FragmentDeviceProvisionBinding private val viewModel: DeviceProvisionViewModel by activityViewModels() @@ -46,13 +38,11 @@ class DeviceProvisionFragment : Fragment() { sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) return binding.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initViews() observeViewModel() } - private fun initViews() { listenToHemoCube() getDeviceId() @@ -66,87 +56,81 @@ class DeviceProvisionFragment : Fragment() { ) ) } - - - - viewModel.deviceData.observe(viewLifecycleOwner) { currentDeviceData = it } - - } + } private fun observeViewModel() { - viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> - when (response) { - is Result.Success -> { - if (response.data.result == "Success") { - with(sharedPreferences.edit()) { - putString( - Constants.DEVICE_ID_API, - response.data.data?.credentials?.username - ) - putString( - Constants.DEVICE_PASSWORD_API, - response.data.data?.credentials?.password - ) - putString( - Constants.NATS_TOKEN, - response.data.data?.device?.deviceUser?.natsToken - ) - putString( - Constants.NATS_TOKEN_EXPIRE_DATE, - response.data.data?.device?.deviceUser?.natsTokenExpiry - ) - apply() - } - startActivity( - Intent( - requireContext(), - DashboardActivity::class.java - ) - ) - Toast.makeText( - activity, "Device registered successfully", Toast.LENGTH_LONG - ).show() - - viewModel.addDeviceProvisionDataToDb( - DeviceData( - deviceProvisionResponse = response.toString() - ) - ) - - } else { - Toast.makeText( - activity, - "An error in device provision: ${response.data.message}", - Toast.LENGTH_LONG - ).show() - binding.btnSubmit.visibility = View.VISIBLE - } - + viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> + when (response) { + is Result.Success -> { + if (response.data.result == "Success") { + with(sharedPreferences.edit()) { + putString( + Constants.DEVICE_ID_API, + response.data.data?.credentials?.username + ) + putString( + Constants.DEVICE_PASSWORD_API, + response.data.data?.credentials?.password + ) + putString( + Constants.NATS_TOKEN, + response.data.data?.device?.deviceUser?.natsToken + ) + putString( + Constants.NATS_TOKEN_EXPIRE_DATE, + response.data.data?.device?.deviceUser?.natsTokenExpiry + ) + apply() } + startActivity( + Intent( + requireContext(), + DashboardActivity::class.java + ) + ) + Toast.makeText( + activity, "Device registered successfully", Toast.LENGTH_LONG + ).show() - is Result.Error -> { - response.exception.let { message -> - Toast.makeText( - activity, - "An error occurred in device provision: $message", - Toast.LENGTH_LONG - ).show() - } - } + viewModel.addDeviceProvisionDataToDb( + DeviceData( + deviceProvisionResponse = response.toString() + ) + ) + } else { + Toast.makeText( + activity, + "An error in device provision: ${response.data.message}", + Toast.LENGTH_LONG + ).show() + binding.btnSubmit.visibility = View.VISIBLE + } - is Result.Loading -> { - binding.btnSubmit.visibility = View.GONE - } + } - else -> {} + is Result.Error -> { + response.exception.let { message -> + Toast.makeText( + activity, + "An error occurred in device provision: $message", + Toast.LENGTH_LONG + ).show() } } + is Result.Loading -> { + binding.btnSubmit.visibility = View.GONE + } + + else -> {} + } + } + } @@ -164,7 +148,8 @@ class DeviceProvisionFragment : Fragment() { val fullReadOutput = StringBuilder() try { - (activity as DeviceProvisionActivity).mService.listenToHemoCube(object : UsbServiceListener { + (activity as DeviceProvisionActivity).mService.listenToHemoCube(object : + UsbServiceListener { override fun onUsbRead(data: ByteArray?) { data?.let { val stringData = String(it) @@ -180,7 +165,6 @@ class DeviceProvisionFragment : Fragment() { Firebase.crashlytics.recordException(e) } } - private fun handleUsbData() { when { resultData.contains("SNE") -> { From c5cb8a09830f50c95c403166fd878dfe11c2bae3 Mon Sep 17 00:00:00 2001 From: Mariya Date: Thu, 8 Feb 2024 14:24:34 +0530 Subject: [PATCH 3/8] Added code for fetching response of device provision api from firebase --- .../model/deviceprovision/ProvisionData.kt | 8 ++ .../presentation/dashboard/HomeFragment.kt | 76 ++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/example/hpostesting/data/model/deviceprovision/ProvisionData.kt diff --git a/app/src/main/java/com/example/hpostesting/data/model/deviceprovision/ProvisionData.kt b/app/src/main/java/com/example/hpostesting/data/model/deviceprovision/ProvisionData.kt new file mode 100644 index 0000000..179ea33 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/model/deviceprovision/ProvisionData.kt @@ -0,0 +1,8 @@ +package com.example.hpostesting.data.model.deviceprovision + +data class ProvisionData( +val username: String?, +val password: String?, +val natsToken: String? +) + 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 97d6094..b994f75 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 @@ -1,6 +1,7 @@ package com.example.hpostesting.presentation.dashboard import android.app.AlertDialog +import android.content.ContentValues.TAG import android.content.Context import android.content.Context.BATTERY_SERVICE import android.content.DialogInterface @@ -20,10 +21,12 @@ import androidx.navigation.fragment.findNavController import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.Result import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.deviceprovision.ProvisionData import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.molbioresult.MolbioV2Result import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest +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.updates.CheckUpdateRequest @@ -35,11 +38,14 @@ import com.example.hpostesting.presentation.assurance.AssuranceControlsActivity import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.testRight.TestRightViewModel import com.firebase.ui.firestore.FirestoreRecyclerOptions +import com.google.common.reflect.TypeToken import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.firestore.Query import com.google.firebase.firestore.ktx.firestore import com.google.firebase.ktx.Firebase import com.google.firebase.perf.ktx.performance +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding @@ -62,6 +68,10 @@ class HomeFragment : Fragment() { private val homeViewModel: HemoCubeViewModel by activityViewModels() private var isTokenAvailable = false + private var username:String ="" + private var passworD:String ="" + private var natsToken:String ="" + private lateinit var sharedPreference: SharedPreferences override fun onCreateView( @@ -186,12 +196,16 @@ class HomeFragment : Fragment() { binding.downloadCSV.setOnClickListener { showDownloadDialog(requireContext()) } + } private fun checkForTokenAndUpdate() { val accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() val password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString() - val userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString() + var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString() + fetchDeviceProvisionResponse(deviceId = Constants.DEVICE_ID) + val devuserid = username + val devpassword = passworD if (userID.isNotEmpty() && password.isNotEmpty()) { if (accessToken.isEmpty()) { hemoCubeViewModel.login(createLoginRequestData(userID, password)) @@ -205,7 +219,21 @@ class HomeFragment : Fragment() { hemoCubeViewModel.startPeriodicCheckUpdate() } } - } else { + } else if(devuserid.isNotEmpty() && devpassword.isNotEmpty()){ + hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) + if (accessToken.isEmpty()) { + hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) + } else { + if (isTokenExpired(accessToken)) { + hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) + } else { + isTokenAvailable = true + hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) + hemoCubeViewModel.uploadLogs() + hemoCubeViewModel.startPeriodicCheckUpdate() + } + } + }else{ Toast.makeText( requireContext(), "Contact Help and get your device provision done", @@ -366,6 +394,50 @@ class HomeFragment : Fragment() { } } + + private fun fetchDeviceProvisionResponse(deviceId: String) { + val db = Firebase.firestore + val deviceRef = db.collection("devices").document(deviceId) + + deviceRef.get() + .addOnSuccessListener { document -> + if (document.exists()) { + val deviceData = document.toObject(DeviceData::class.java) + val deviceProvisionResponse = deviceData?.deviceProvisionResponse + + // Parse the deviceProvisionResponse to extract username, password, natsToken + val provisionData = deviceProvisionResponse?.let { + parseDeviceProvisionResponse( + it + ) + } + provisionData?.let { data -> + username = data.username.toString() + passworD = data.password.toString() + natsToken = data.natsToken.toString() + } + } else { + // Handle the case where the device document doesn't exist + } + } + .addOnFailureListener { exception -> + // Handle any errors + Log.e(TAG, "Error fetching device data: $exception") + } + } + + fun parseDeviceProvisionResponse(responseString: String): ProvisionData? { + return try { + val gson = Gson() + val type = object : TypeToken() {}.type + gson.fromJson(responseString, type) + } catch (e: JsonSyntaxException) { + null + } + } + + + private fun loadUserData() { try { val dateFormat = SimpleDateFormat("yyyy-MM-dd") From 89dc7f723489905dc7bb2df6f6dcaa5d20ab27ca Mon Sep 17 00:00:00 2001 From: Mariya Date: Fri, 9 Feb 2024 16:39:02 +0530 Subject: [PATCH 4/8] Added code related to device provision fetching fromfirestore --- .../presentation/dashboard/HomeFragment.kt | 50 +++++++++++-------- .../DeviceProvisionFragment.kt | 2 + .../DeviceProvisionViewModel.kt | 12 +++++ 3 files changed, 43 insertions(+), 21 deletions(-) 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 b994f75..5778038 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 @@ -120,9 +120,15 @@ class HomeFragment : Fragment() { binding.rvOrderOffline.adapter = adapter } } + hemoCubeViewModel.deviceData.observe(viewLifecycleOwner){ deviceData-> + val devicelist = mutableListOf() + if (deviceData != null) { + devicelist.add(DeviceData(deviceData.deviceId)) + } + + } viewModel.networkStatusLiveData?.observe(viewLifecycleOwner) { isConnected -> if (isConnected) { - binding.internetAvailableCL.visibility = View.VISIBLE binding.internetNotAvailableCL.visibility = View.GONE loadUserData() @@ -201,12 +207,18 @@ class HomeFragment : Fragment() { private fun checkForTokenAndUpdate() { val accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() - val password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString() + var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString() var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString() - fetchDeviceProvisionResponse(deviceId = Constants.DEVICE_ID) - val devuserid = username - val devpassword = passworD - if (userID.isNotEmpty() && password.isNotEmpty()) { + val deviceId = sharedPreference.getString(Constants.DEVICE_ID,"") + + if(userID.isEmpty() && password.isEmpty()){ + if (deviceId != null) { + fetchDeviceProvisionResponse(deviceId) + } + userID = sharedPreference.getString("username",username).toString() + password = sharedPreference.getString("password",passworD).toString() + hemoCubeViewModel.login(createLoginRequestData(userID, password)) + }else if (userID.isNotEmpty() && password.isNotEmpty()) { if (accessToken.isEmpty()) { hemoCubeViewModel.login(createLoginRequestData(userID, password)) } else { @@ -219,20 +231,6 @@ class HomeFragment : Fragment() { hemoCubeViewModel.startPeriodicCheckUpdate() } } - } else if(devuserid.isNotEmpty() && devpassword.isNotEmpty()){ - hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) - if (accessToken.isEmpty()) { - hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) - } else { - if (isTokenExpired(accessToken)) { - hemoCubeViewModel.login(createLoginRequestData(devuserid, devpassword)) - } else { - isTokenAvailable = true - hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) - hemoCubeViewModel.uploadLogs() - hemoCubeViewModel.startPeriodicCheckUpdate() - } - } }else{ Toast.makeText( requireContext(), @@ -412,10 +410,20 @@ class HomeFragment : Fragment() { ) } provisionData?.let { data -> + // Assuming 'data' has the fields 'username', 'password', and 'natsToken' username = data.username.toString() passworD = data.password.toString() natsToken = data.natsToken.toString() + + // Assuming 'sharedPreference' is correctly initialized SharedPreferences instance + with(sharedPreference.edit()) { + putString("username", username) // Replace "username_key" with your actual key for username + putString("password", passworD) // Replace "password_key" with your actual key for password + putString("natsToken", natsToken) // Replace "natsToken_key" with your actual key for NATS token + apply() // Don't forget to call apply() to save the changes + } } + } else { // Handle the case where the device document doesn't exist } @@ -426,7 +434,7 @@ class HomeFragment : Fragment() { } } - fun parseDeviceProvisionResponse(responseString: String): ProvisionData? { + private fun parseDeviceProvisionResponse(responseString: String): ProvisionData? { return try { val gson = Gson() val type = object : TypeToken() {}.type diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index a86fc25..954bb44 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -97,6 +97,8 @@ class DeviceProvisionFragment : Fragment() { activity, "Device registered successfully", Toast.LENGTH_LONG ).show() + response.data.data?.credentials?.username?.let { DeviceData(deviceId = it) } + ?.let { viewModel.addDeviceId(it) } viewModel.addDeviceProvisionDataToDb( DeviceData( deviceProvisionResponse = response.toString() diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt index aa0be0c..bc83159 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt @@ -38,6 +38,18 @@ class DeviceProvisionViewModel @Inject constructor( } } + + fun addDeviceId(data: DeviceData){ + viewModelScope.launch { + try{ + val id = repository.getDeviceDataById(data.deviceId) + fireBaseUpload.postValue("Success") + } catch (e: Exception) { +// Log.e("Testdb", "Exception during data upload: ${e.message}") + fireBaseUpload.postValue("Error") + } + } + } fun addDeviceProvisionDataToDb(data: DeviceData) { viewModelScope.launch { try { From d5b691040857277c05c274e5e9b505c0c1e2e7ef Mon Sep 17 00:00:00 2001 From: Mariya Date: Sat, 10 Feb 2024 17:37:07 +0530 Subject: [PATCH 5/8] Device provision response storing --- app/build.gradle | 6 +- app/google-services.json | 186 ++++++++++++++++-- .../hpostesting/data/api/PropertyProvider.kt | 9 +- .../data/repository/DatabaseRepository.kt | 18 +- .../hpostesting/data/repository/Repository.kt | 3 +- .../presentation/dashboard/HomeFragment.kt | 123 +++++++++--- .../DeviceProvisionActivity.kt | 9 +- .../DeviceProvisionFragment.kt | 26 ++- .../DeviceProvisionViewModel.kt | 6 +- 9 files changed, 324 insertions(+), 62 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c881eb0..e8912e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,11 +16,11 @@ android { // dev - development, quality - qc, uat - User Acceptance Test, preprod - preproduction, prod - production defaultConfig { - applicationId "in.sminnovations.hpostesting.quality" + applicationId "in.sminnovations.hpostesting" minSdk 21 targetSdk 34 - versionCode 101 - versionName "2.1.101" + versionCode 102 + versionName "2.1.102" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/google-services.json b/app/google-services.json index 7f4a67b..a73fe1e 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -1,45 +1,205 @@ { "project_info": { - "project_number": "1004619739289", - "project_id": "hpos-qa", - "storage_bucket": "hpos-qa.appspot.com" + "project_number": "650071678820", + "project_id": "hpos-af3cc", + "storage_bucket": "hpos-af3cc.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:1004619739289:android:f669b47552748433e5c808", + "mobilesdk_app_id": "1:650071678820:android:f1435a1c07f710036c6471", "android_client_info": { - "package_name": "in.sminnovations.hposregistration.quality" + "package_name": "com.example.hposconsentform" } }, - "oauth_client": [], + "oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], "api_key": [ { - "current_key": "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs" + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" } ], "services": { "appinvite_service": { - "other_platform_oauth_client": [] + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] } } }, { "client_info": { - "mobilesdk_app_id": "1:1004619739289:android:8397cd1f0357bd89e5c808", + "mobilesdk_app_id": "1:650071678820:android:7865bef608cdee6f6c6471", "android_client_info": { - "package_name": "in.sminnovations.hpostesting.quality" + "package_name": "com.smi.counselling" } }, - "oauth_client": [], + "oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], "api_key": [ { - "current_key": "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs" + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" } ], "services": { "appinvite_service": { - "other_platform_oauth_client": [] + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:650071678820:android:2925e9ce3417d2386c6471", + "android_client_info": { + "package_name": "in.sminnovations.hemocube" + } + }, + "oauth_client": [ + { + "client_id": "650071678820-srhm9spm9hjn4frcd3r6o02gdhdbtd15.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "in.sminnovations.hemocube", + "certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a" + } + }, + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:650071678820:android:7569c1cad4fc99916c6471", + "android_client_info": { + "package_name": "in.sminnovations.hposregistration" + } + }, + "oauth_client": [ + { + "client_id": "650071678820-70kp5jvjda4r5diqch2kn4lc40p4f42g.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "in.sminnovations.hposregistration", + "certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a" + } + }, + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:650071678820:android:f96be19e5d43102b6c6471", + "android_client_info": { + "package_name": "in.sminnovations.hpostesting" + } + }, + "oauth_client": [ + { + "client_id": "650071678820-l87dnr0bdj95get0khgnvfv2an1k6ogq.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "in.sminnovations.hpostesting", + "certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a" + } + }, + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:650071678820:android:a53292637abb7c0d6c6471", + "android_client_info": { + "package_name": "in.sminnovations.hpostesting.dev" + } + }, + "oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", + "client_type": 3 + } + ] } } } diff --git a/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt b/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt index 5f55ac4..12486ec 100644 --- a/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt +++ b/app/src/main/java/com/example/hpostesting/data/api/PropertyProvider.kt @@ -1,6 +1,13 @@ package com.example.hpostesting.data.api +import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.presentation.UsbServiceListener + interface PropertyProvider { fun getProperty(key: String): String -} \ No newline at end of file +} + +interface DeviceCommunicationHandler { + fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) +} 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 0812cd6..1329854 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 @@ -203,8 +203,7 @@ class DatabaseRepository @Inject constructor( return allDeviceDataList.find { it.deviceId == deviceId } } - - override suspend fun getDeviceResponse(data: DeviceData): Response? { + override suspend fun getDeviceResponse(data: DeviceData?): Response { return try { db.collection("devices").add(data!!).await() Response.Success(data.deviceProvisionResponse) @@ -213,7 +212,22 @@ class DatabaseRepository @Inject constructor( Response.Error(e) } } + + + + + override suspend fun uploadDeviceId(data: DeviceData): Response? { + return try { + db.collection("devices").add(data!!).await() + Response.Success(data.deviceId) + } catch (e: Exception) { + Firebase.crashlytics.recordException(e) + Response.Error(e) + } + } + override fun addTestToDatabase(testDetails: UserData): Any { TODO("Not yet implemented") } + } \ No newline at end of file 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 ecdad95..6576a5c 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 @@ -32,7 +32,8 @@ interface Repository { suspend fun uploadFileToStorage(patientID: String, filePath: String): Response suspend fun getDeviceDataById(deviceId: String): DeviceData? - suspend fun getDeviceResponse(data: DeviceData): Response? + suspend fun getDeviceResponse(data: DeviceData?): Response + suspend fun uploadDeviceId(data: DeviceData): Response? abstract fun addTestToDatabase(testDetails: UserData): Any // suspend fun addToDatabase(data: PatientDetails) 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 5778038..3538078 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,7 +20,9 @@ import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.Result +import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.model.deviceprovision.ProvisionData import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginResponse @@ -32,6 +34,7 @@ import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.presentation.KitScanActivity +import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter import com.example.hpostesting.presentation.adapter.UserListAdapter import com.example.hpostesting.presentation.assurance.AssuranceControlsActivity @@ -49,7 +52,9 @@ import com.google.gson.JsonSyntaxException import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding +import org.json.JSONException import org.json.JSONObject +import java.nio.charset.Charset import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date @@ -68,9 +73,10 @@ class HomeFragment : Fragment() { private val homeViewModel: HemoCubeViewModel by activityViewModels() private var isTokenAvailable = false - private var username:String ="" - private var passworD:String ="" - private var natsToken:String ="" + private var username: String = "" + private var passworD: String = "" + private var natsToken: String = "" + private var deviceId: String = "" private lateinit var sharedPreference: SharedPreferences @@ -120,7 +126,7 @@ class HomeFragment : Fragment() { binding.rvOrderOffline.adapter = adapter } } - hemoCubeViewModel.deviceData.observe(viewLifecycleOwner){ deviceData-> + hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { deviceData -> val devicelist = mutableListOf() if (deviceData != null) { devicelist.add(DeviceData(deviceData.deviceId)) @@ -134,6 +140,7 @@ class HomeFragment : Fragment() { loadUserData() setSearch() checkForLocalDBData() + getDeviceId() checkForTokenAndUpdate() } else { binding.internetAvailableCL.visibility = View.GONE @@ -206,19 +213,14 @@ class HomeFragment : Fragment() { } private fun checkForTokenAndUpdate() { - val accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() + var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString() var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString() - val deviceId = sharedPreference.getString(Constants.DEVICE_ID,"") - - if(userID.isEmpty() && password.isEmpty()){ - if (deviceId != null) { - fetchDeviceProvisionResponse(deviceId) - } - userID = sharedPreference.getString("username",username).toString() - password = sharedPreference.getString("password",passworD).toString() - hemoCubeViewModel.login(createLoginRequestData(userID, password)) - }else if (userID.isNotEmpty() && password.isNotEmpty()) { + deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString() + Log.e("idpass", userID) + Log.e("idpass", password) + Log.e("idpass", deviceId) + if (userID.isNotEmpty() && password.isNotEmpty()) { if (accessToken.isEmpty()) { hemoCubeViewModel.login(createLoginRequestData(userID, password)) } else { @@ -231,7 +233,12 @@ class HomeFragment : Fragment() { hemoCubeViewModel.startPeriodicCheckUpdate() } } - }else{ + }else if (deviceId.isNotEmpty()) { + fetchDeviceProvisionResponse() + userID = username + password = passworD + hemoCubeViewModel.login(createLoginRequestData(userID, password)) + } else { Toast.makeText( requireContext(), "Contact Help and get your device provision done", @@ -393,10 +400,12 @@ class HomeFragment : Fragment() { } - private fun fetchDeviceProvisionResponse(deviceId: String) { + private fun fetchDeviceProvisionResponse() { val db = Firebase.firestore + val deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString() val deviceRef = db.collection("devices").document(deviceId) + deviceRef.get() .addOnSuccessListener { document -> if (document.exists()) { @@ -411,15 +420,24 @@ class HomeFragment : Fragment() { } provisionData?.let { data -> // Assuming 'data' has the fields 'username', 'password', and 'natsToken' - username = data.username.toString() - passworD = data.password.toString() - natsToken = data.natsToken.toString() + username = data.username.toString() + passworD = data.password.toString() + natsToken = data.natsToken.toString() // Assuming 'sharedPreference' is correctly initialized SharedPreferences instance with(sharedPreference.edit()) { - putString("username", username) // Replace "username_key" with your actual key for username - putString("password", passworD) // Replace "password_key" with your actual key for password - putString("natsToken", natsToken) // Replace "natsToken_key" with your actual key for NATS token + putString( + "username", + username + ) // Replace "username_key" with your actual key for username + putString( + "password", + passworD + ) // Replace "password_key" with your actual key for password + putString( + "natsToken", + natsToken + ) // Replace "natsToken_key" with your actual key for NATS token apply() // Don't forget to call apply() to save the changes } } @@ -436,16 +454,21 @@ class HomeFragment : Fragment() { private fun parseDeviceProvisionResponse(responseString: String): ProvisionData? { return try { - val gson = Gson() - val type = object : TypeToken() {}.type - gson.fromJson(responseString, type) - } catch (e: JsonSyntaxException) { + val jsonObject = JSONObject(responseString) + + val credentials = jsonObject.getJSONObject("credentials") + val username = credentials.getString("username") + val password = credentials.getString("password") + + val deviceUser = jsonObject.getJSONObject("device").getJSONObject("deviceUser") + val natsToken = deviceUser.getString("natsToken") + + ProvisionData(username, password, natsToken) + } catch (e: JSONException) { null } } - - private fun loadUserData() { try { val dateFormat = SimpleDateFormat("yyyy-MM-dd") @@ -828,4 +851,44 @@ class HomeFragment : Fragment() { } } } -} \ No newline at end of file + + private fun getDeviceId() { + val handler = activity as? DeviceCommunicationHandler + handler?.sendAndListenToDevice( + HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, + object : UsbServiceListener { + override fun onUsbRead(data: ByteArray?) { + data?.let { + val receivedData = String(it, Charset.forName("UTF-8")) + // Assuming the device ID is the full content of the received data. Adjust if needed. + deviceId = + extractDeviceId(receivedData) // Implement this method based on your data format. + if (deviceId.isNotEmpty()) { + // Store the deviceId in SharedPreferences + with(sharedPreference.edit()) { + putString(Constants.DEVICE_ID, deviceId) + apply() + } + // Optionally, you can update UI or proceed with further logic now that you have the device ID + activity?.runOnUiThread { + // Update your UI or trigger next steps here + } + } + } + } + + override fun onUsbError(e: Exception?) { + // Handle USB communication error + } + + }) + } + + fun extractDeviceId(receivedData: String): String { + // Example based on the format "SNS HPP1-3038 SNE" + val regex = "SNS (\\w+) SNE".toRegex() + val matchResult = regex.find(receivedData) + return matchResult?.groups?.get(1)?.value ?: "" + } + +} diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt index 1e316ff..1e2c5bd 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionActivity.kt @@ -21,8 +21,11 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.get import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.LanguageManager +import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.testRight.UsbService import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialProber @@ -31,7 +34,7 @@ import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding @AndroidEntryPoint -class DeviceProvisionActivity : AppCompatActivity() { +class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler { private lateinit var binding: ActivityAutoDacBinding val viewModel: DeviceProvisionViewModel by viewModels() private var myMenu: Menu? = null @@ -180,4 +183,8 @@ class DeviceProvisionActivity : AppCompatActivity() { viewModel.isServiceConnected = false } } + + override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) { + mService.sendAndListenToHemoCube(command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, listener) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index 954bb44..bbb4ea2 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -20,6 +21,7 @@ import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase +import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding class DeviceProvisionFragment : Fragment() { @@ -56,13 +58,13 @@ class DeviceProvisionFragment : Fragment() { ) ) } - viewModel.deviceData.observe(viewLifecycleOwner) { - currentDeviceData = it - } } private fun observeViewModel() { + viewModel.deviceData.observe(viewLifecycleOwner) { + currentDeviceData = it + } viewModel.deviceProvisionResponse.observe(viewLifecycleOwner) { response -> when (response) { @@ -96,14 +98,16 @@ class DeviceProvisionFragment : Fragment() { Toast.makeText( activity, "Device registered successfully", Toast.LENGTH_LONG ).show() - - response.data.data?.credentials?.username?.let { DeviceData(deviceId = it) } - ?.let { viewModel.addDeviceId(it) } viewModel.addDeviceProvisionDataToDb( DeviceData( - deviceProvisionResponse = response.toString() + deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), + deviceProvisionResponse = response.data.data.toString() ) ) +// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString())) + Log.e("idpass",response.toString()) + Log.e("idpass",response.data.data?.credentials?.username.toString()) + Log.e("idpass",deviceProvisionResponse) } else { Toast.makeText( activity, @@ -132,7 +136,13 @@ class DeviceProvisionFragment : Fragment() { else -> {} } } - + viewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> + if (result == "Success") { + Toast.makeText( + activity, "Device provision successfully uploaded to firebase", Toast.LENGTH_LONG + ).show() + } + } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt index bc83159..f2cd209 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt @@ -42,8 +42,8 @@ class DeviceProvisionViewModel @Inject constructor( fun addDeviceId(data: DeviceData){ viewModelScope.launch { try{ - val id = repository.getDeviceDataById(data.deviceId) - fireBaseUpload.postValue("Success") + repository.uploadDeviceId(data) + fireBaseUpload.postValue("Successfully device Id uploaded to firebase") } catch (e: Exception) { // Log.e("Testdb", "Exception during data upload: ${e.message}") fireBaseUpload.postValue("Error") @@ -56,7 +56,7 @@ class DeviceProvisionViewModel @Inject constructor( when (val response = repository.getDeviceResponse(data)) { is Response.Success -> { // Log.i("Testdb", "Data uploaded to Firestore successfully") - fireBaseUpload.postValue("Success") + fireBaseUpload.postValue("Successfully device response uploaded to firebase") } is Response.Error -> { From 7f47e1dff871edc16d9aa9c62baf6563d15e58a8 Mon Sep 17 00:00:00 2001 From: Mariya Date: Mon, 12 Feb 2024 12:01:10 +0530 Subject: [PATCH 6/8] Device provision username and password stored in firebase store separately --- .../example/hpostesting/data/model/patient/DeviceData.kt | 6 +++++- .../presentation/deviceprovision/DeviceProvisionFragment.kt | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/DeviceData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/DeviceData.kt index 99dfbe2..5ccb755 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/DeviceData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/DeviceData.kt @@ -18,6 +18,10 @@ data class DeviceData( @get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt") var calibratedAt: String = "" , @get:PropertyName("deviceProvisionResponse") @set:PropertyName("deviceProvisionResponse") - var deviceProvisionResponse: String = "" + var deviceProvisionResponse: String = "" , + @get:PropertyName("username") @set:PropertyName("username") + var username: String = "", + @get:PropertyName("password") @set:PropertyName("password") + var password: String = "" ) \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index bbb4ea2..ba62f33 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -101,6 +101,8 @@ class DeviceProvisionFragment : Fragment() { viewModel.addDeviceProvisionDataToDb( DeviceData( deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), + username = response.data.data?.credentials?.username.toString(), + password = response.data.data?.credentials?.password.toString(), deviceProvisionResponse = response.data.data.toString() ) ) From 9314b155cd417ad29184c8a933f261f17ca679bf Mon Sep 17 00:00:00 2001 From: Mariya Date: Mon, 12 Feb 2024 13:56:05 +0530 Subject: [PATCH 7/8] Device provision fetching code is added --- .../hpostesting/data/dao/MyDataBase.kt | 2 +- .../dashboard/DashboardActivity.kt | 4 + .../presentation/dashboard/HomeFragment.kt | 125 +++++++----------- .../presentation/deviceinfo/DeviceActivity.kt | 9 +- 4 files changed, 61 insertions(+), 79 deletions(-) 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 7cb221a..95a8940 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 @@ -8,7 +8,7 @@ import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.UserData -@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class], version = 24, exportSchema = false) +@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class], version = 25, exportSchema = false) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt index 63b7cd9..48944c6 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt @@ -19,9 +19,13 @@ import androidx.navigation.ui.navigateUp import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import com.example.hpostesting.data.Result +import com.example.hpostesting.data.api.DeviceCommunicationHandler +import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.presentation.NatsManager +import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel +import com.example.hpostesting.presentation.testRight.UsbService import com.google.android.material.navigation.NavigationView import com.google.firebase.appdistribution.FirebaseAppDistribution import com.google.firebase.appdistribution.FirebaseAppDistributionException 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 3538078..949e0a3 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 @@ -1,7 +1,6 @@ package com.example.hpostesting.presentation.dashboard import android.app.AlertDialog -import android.content.ContentValues.TAG import android.content.Context import android.content.Context.BATTERY_SERVICE import android.content.DialogInterface @@ -23,7 +22,6 @@ import com.example.hpostesting.data.Result import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands -import com.example.hpostesting.data.model.deviceprovision.ProvisionData import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.molbioresult.MolbioV2Result @@ -41,18 +39,14 @@ import com.example.hpostesting.presentation.assurance.AssuranceControlsActivity import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.testRight.TestRightViewModel import com.firebase.ui.firestore.FirestoreRecyclerOptions -import com.google.common.reflect.TypeToken import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.firestore.Query import com.google.firebase.firestore.ktx.firestore import com.google.firebase.ktx.Firebase import com.google.firebase.perf.ktx.performance -import com.google.gson.Gson -import com.google.gson.JsonSyntaxException import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding -import org.json.JSONException import org.json.JSONObject import java.nio.charset.Charset import java.text.SimpleDateFormat @@ -73,8 +67,6 @@ class HomeFragment : Fragment() { private val homeViewModel: HemoCubeViewModel by activityViewModels() private var isTokenAvailable = false - private var username: String = "" - private var passworD: String = "" private var natsToken: String = "" private var deviceId: String = "" @@ -105,7 +97,7 @@ class HomeFragment : Fragment() { binding.labelQuickCapture.visibility = View.VISIBLE binding.btnQuickCapture.visibility = View.VISIBLE } - + getDeviceId() checkUnprocessedCSVData() viewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteIncompleteRegistrations(userData) @@ -140,7 +132,6 @@ class HomeFragment : Fragment() { loadUserData() setSearch() checkForLocalDBData() - getDeviceId() checkForTokenAndUpdate() } else { binding.internetAvailableCL.visibility = View.GONE @@ -234,11 +225,21 @@ class HomeFragment : Fragment() { } } }else if (deviceId.isNotEmpty()) { - fetchDeviceProvisionResponse() - userID = username - password = passworD - hemoCubeViewModel.login(createLoginRequestData(userID, password)) - } else { + fetchDeviceCredentials() + // This code will execute after credentials have been successfully fetched and stored. + userID = sharedPreference.getString("username", "").toString() + password = sharedPreference.getString("password", "").toString() + accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() + if (accessToken.isEmpty()) { + hemoCubeViewModel.login(createLoginRequestData(userID, password)) + } else { + // Continue with your existing logic if the token is not empty. + isTokenAvailable = true + hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) + hemoCubeViewModel.uploadLogs() + hemoCubeViewModel.startPeriodicCheckUpdate() + } + } else { Toast.makeText( requireContext(), "Contact Help and get your device provision done", @@ -400,75 +401,45 @@ class HomeFragment : Fragment() { } - private fun fetchDeviceProvisionResponse() { - val db = Firebase.firestore - val deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString() - val deviceRef = db.collection("devices").document(deviceId) + private fun fetchDeviceCredentials() { + try { + val db = Firebase.firestore + // Ensure deviceId is not null or empty + val deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").takeIf { it!!.isNotBlank() } + ?: throw IllegalStateException("Device ID is missing or blank.") + val deviceRef = db.collection("devices").whereEqualTo("deviceId", deviceId) - deviceRef.get() - .addOnSuccessListener { document -> - if (document.exists()) { - val deviceData = document.toObject(DeviceData::class.java) - val deviceProvisionResponse = deviceData?.deviceProvisionResponse - - // Parse the deviceProvisionResponse to extract username, password, natsToken - val provisionData = deviceProvisionResponse?.let { - parseDeviceProvisionResponse( - it - ) + deviceRef.get() + .addOnSuccessListener { documentSnapshot -> + if (!documentSnapshot.isEmpty) { + val deviceData = documentSnapshot.documents[0].toObject(DeviceData::class.java) + deviceData?.let { data -> + val username = data.username + val password = data.password + // Log for debugging + Log.d("fetchDeviceCredentials", "Username: $username, Password: $password") + // Save credentials in SharedPreferences + with(sharedPreference.edit()) { + putString("username", username) + putString("password", password) + apply() + } + hemoCubeViewModel.login(createLoginRequestData(username, password)) + } ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.") + } else { + Log.e("fetchDeviceCredentials", "Document does not exist.") } - provisionData?.let { data -> - // Assuming 'data' has the fields 'username', 'password', and 'natsToken' - username = data.username.toString() - passworD = data.password.toString() - natsToken = data.natsToken.toString() - - // Assuming 'sharedPreference' is correctly initialized SharedPreferences instance - with(sharedPreference.edit()) { - putString( - "username", - username - ) // Replace "username_key" with your actual key for username - putString( - "password", - passworD - ) // Replace "password_key" with your actual key for password - putString( - "natsToken", - natsToken - ) // Replace "natsToken_key" with your actual key for NATS token - apply() // Don't forget to call apply() to save the changes - } - } - - } else { - // Handle the case where the device document doesn't exist } - } - .addOnFailureListener { exception -> - // Handle any errors - Log.e(TAG, "Error fetching device data: $exception") - } - } - - private fun parseDeviceProvisionResponse(responseString: String): ProvisionData? { - return try { - val jsonObject = JSONObject(responseString) - - val credentials = jsonObject.getJSONObject("credentials") - val username = credentials.getString("username") - val password = credentials.getString("password") - - val deviceUser = jsonObject.getJSONObject("device").getJSONObject("deviceUser") - val natsToken = deviceUser.getString("natsToken") - - ProvisionData(username, password, natsToken) - } catch (e: JSONException) { - null + .addOnFailureListener { exception -> + Log.e("fetchDeviceCredentials", "Error fetching device data", exception) + } + } catch (e: Exception) { + Log.e("fetchDeviceCredentials", "Error in fetchDeviceCredentials", e) } } + private fun loadUserData() { try { val dateFormat = SimpleDateFormat("yyyy-MM-dd") diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt index 60db0cd..53fd89c 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt @@ -22,8 +22,11 @@ import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.core.view.get import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.api.DeviceCommunicationHandler import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.LanguageManager +import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.testRight.UsbService import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialProber @@ -33,7 +36,7 @@ import `in`.sminnovations.hpostesting.databinding.ActivityDeviceBinding @Suppress("MemberVisibilityCanBePrivate") @AndroidEntryPoint -class DeviceActivity : AppCompatActivity() { +class DeviceActivity : AppCompatActivity(), DeviceCommunicationHandler { private lateinit var binding: ActivityDeviceBinding private val deviceViewModel by viewModels() private var myMenu: Menu? = null @@ -177,4 +180,8 @@ class DeviceActivity : AppCompatActivity() { deviceViewModel.isServiceConnected = false } } + + override fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) { + mService.sendAndListenToHemoCube(command = HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, listener) + } } \ No newline at end of file From 80eb658b07a840741ea26ea137cce892f2bfd9f7 Mon Sep 17 00:00:00 2001 From: Mariya Date: Mon, 12 Feb 2024 17:56:37 +0530 Subject: [PATCH 8/8] changes when we tested --- app/build.gradle | 6 +++--- app/src/main/AndroidManifest.xml | 2 +- .../hpostesting/presentation/dashboard/DashboardActivity.kt | 2 +- .../hpostesting/presentation/dashboard/GalleryFragment.kt | 2 +- .../presentation/deviceprovision/DeviceProvisionFragment.kt | 4 ++-- app/src/main/res/layout/fragment_gallery.xml | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e8912e3..8a0a2be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,11 +16,11 @@ android { // dev - development, quality - qc, uat - User Acceptance Test, preprod - preproduction, prod - production defaultConfig { - applicationId "in.sminnovations.hpostesting" + applicationId "in.sminnovations.hpostesting.dev" minSdk 21 targetSdk 34 - versionCode 102 - versionName "2.1.102" + versionCode 111 + versionName "2.1.111" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c4d08b5..7a35c8a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -159,7 +159,7 @@ { - val pattern = Regex("HPP1-\\d{4}") + val pattern = Regex("HCV-\\d{3}-\\d{4}") val matchResult = pattern.find(resultData) val hardwareId = matchResult?.value - if (hardwareId.toString().length == 9) { + if (hardwareId.toString().length == 12) { with(sharedPreferences.edit()) { putString(Constants.DEVICE_ID, hardwareId) apply() diff --git a/app/src/main/res/layout/fragment_gallery.xml b/app/src/main/res/layout/fragment_gallery.xml index fd82fc3..1c94d59 100644 --- a/app/src/main/res/layout/fragment_gallery.xml +++ b/app/src/main/res/layout/fragment_gallery.xml @@ -77,13 +77,13 @@ app:cornerRadius="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/btn_auto_dac" /> + app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" /> + app:layout_constraintTop_toBottomOf="@id/btn_auto_dac" />