[+] Record log

This commit is contained in:
Azalea Gui
2023-01-23 22:20:43 -05:00
parent d536df4ac9
commit 2a2283607b
@@ -3,21 +3,21 @@ package org.hydev.wearsync
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.*
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.influxdb.client.kotlin.InfluxDBClientKotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.consumeAsFlow
import org.hydev.wearsync.ActivityPermissions.Companion.hasPermissions
import org.hydev.wearsync.bles.BluetoothHandler
import org.hydev.wearsync.bles.BluetoothHandler.Companion.ble
import org.hydev.wearsync.bles.ObservationUnit
import org.hydev.wearsync.databinding.ActivityMainBinding
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity()
@@ -43,21 +43,30 @@ class MainActivity : AppCompatActivity()
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
binding.content.recycler.let {
it.adapter = RecordAdapter(records)
it.layoutManager = LinearLayoutManager(this)
}
if (!hasPermissions()) permissionCallback.launch(intent<ActivityPermissions>())
else afterPermissions()
}
val permissionCallback = actCallback { afterPermissions() }
fun afterPermissions() {
addRecord("Permissions granted")
scope.launch {
// Open settings if influx database is inaccessible
if (runCatching { prefs.influxPing() }.isFailure) settingsCallback.launch(intent<ActivitySettings>())
else afterSettings()
else runOnUiThread { afterSettings() }
}
}
val settingsCallback = actCallback { afterSettings() }
fun afterSettings() {
addRecord("InfluxDB settings checked")
// Create client
influx = prefs.createInflux()
@@ -66,9 +75,12 @@ class MainActivity : AppCompatActivity()
}
val connectCallback = actCallback {
addRecord("Device connected")
// Start collection
binding.content.tvDevice.text = "Configured Device: ${prefs.chosenDevice}"
binding.content.tvValue.text = "Service started!"
startCollect()
}
@@ -102,86 +114,55 @@ class MainActivity : AppCompatActivity()
}
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val dateFormat: DateFormat = SimpleDateFormat("dd-MM-yyyy HH:mm:ss", Locale.ENGLISH)
private val records = ArrayList<Any>()
class RecordAdapter(val records: List<Any>) : RecyclerView.Adapter<RecordAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val type = itemView.findViewById<TextView>(R.id.rrType)
val value = itemView.findViewById<TextView>(R.id.rrValue)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder
{
return ViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.recycler_record, parent, false))
}
override fun getItemCount() = records.size
override fun onBindViewHolder(holder: ViewHolder, position: Int)
{
val record = records[position]
val cls = record.javaClass.name
holder.type.text = cls
holder.value.text = record.toString().replace(cls, "")
if (record is Exception) holder.type.setTextColor(Color.parseColor("#FF6C52"))
}
}
@SuppressLint("NotifyDataSetChanged")
fun addRecord(t: Any) {
while (records.size > 20) records.remove(0)
records.add(t)
runOnUiThread { binding.content.recycler.adapter?.notifyDataSetChanged() }
}
fun startCollect()
{
collectHeartRate(ble)
collectPulseOxContinuous(ble)
collectPulseOxSpot(ble)
collectTemperature(ble)
collectWeight(ble)
collect(ble.heartRateChannel)
collect(ble.batteryChannel)
}
private fun collectHeartRate(bluetoothHandler: BluetoothHandler) {
private fun <T : Any> collect(channel: Channel<T>) {
scope.launch {
bluetoothHandler.heartRateChannel.consumeAsFlow().collect {
withContext(Dispatchers.Main) {
binding.content.tvValue.text = String.format(Locale.ENGLISH, "%d bpm", it.pulse)
channel.consumeAsFlow().collect {
try {
addRecord(it)
influx add it
}
influx add it
}
}
}
private fun collectPulseOxContinuous(bluetoothHandler: BluetoothHandler) {
scope.launch {
bluetoothHandler.pulseOxContinuousChannel.consumeAsFlow().collect {
withContext(Dispatchers.Main) {
binding.content.tvValue.text = String.format(
Locale.ENGLISH,
"SpO2 %d%%, Pulse %d bpm\n%s\n\nfrom %s",
it.spO2,
it.pulseRate,
dateFormat.format(Calendar.getInstance())
)
}
}
}
}
private fun collectPulseOxSpot(bluetoothHandler: BluetoothHandler) {
scope.launch {
bluetoothHandler.pulseOxSpotChannel.consumeAsFlow().collect {
withContext(Dispatchers.Main) {
binding.content.tvValue.text = String.format(
Locale.ENGLISH,
"SpO2 %d%%, Pulse %d bpm\n",
it.spO2,
it.pulseRate
)
}
}
}
}
private fun collectTemperature(bluetoothHandler: BluetoothHandler) {
scope.launch {
bluetoothHandler.temperatureChannel.consumeAsFlow().collect {
withContext(Dispatchers.Main) {
binding.content.tvValue.text = String.format(
Locale.ENGLISH,
"%.1f %s (%s)\n%s\n",
it.temperatureValue,
if (it.unit == ObservationUnit.Celsius) "celsius" else "fahrenheit",
it.type,
dateFormat.format(it.timestamp ?: Calendar.getInstance())
)
}
}
}
}
private fun collectWeight(bluetoothHandler: BluetoothHandler) {
scope.launch {
bluetoothHandler.weightChannel.consumeAsFlow().collect {
withContext(Dispatchers.Main) {
binding.content.tvValue.text = String.format(
Locale.ENGLISH,
"%.1f %s\n%s\n",
it.weight, it.unit.toString(),
dateFormat.format(it.timestamp ?: Calendar.getInstance())
)
catch (e: Exception) {
addRecord(e)
}
}
}