From 5e4470d25e09d0234eb14de6fd43c7dd22edbde3 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Fri, 19 Mar 2021 14:33:55 -0700 Subject: [PATCH] Use default scope for file save and display snr --- .../java/com/geeksville/mesh/MainActivity.kt | 21 ++++++++++--------- .../main/java/com/geeksville/mesh/NodeInfo.kt | 3 ++- .../geeksville/mesh/service/MeshService.kt | 5 ++++- .../com/geeksville/mesh/ui/UsersFragment.kt | 9 +++++++- .../main/res/layout/adapter_node_layout.xml | 10 +++++++++ 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 2d2320950..49afe1710 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -60,11 +60,9 @@ import com.google.android.material.tabs.TabLayoutMediator import com.google.protobuf.InvalidProtocolBufferException import com.vorlonsoft.android.rate.AppRate import com.vorlonsoft.android.rate.StoreType -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.cancel +import kotlinx.coroutines.* import java.io.FileOutputStream +import java.lang.Runnable import java.nio.charset.Charset import java.text.DateFormat import java.util.* @@ -559,10 +557,16 @@ class MainActivity : AppCompatActivity(), Logging, CREATE_CSV_FILE -> { if (resultCode == Activity.RESULT_OK) { data?.data?.let { file_uri -> + // model.allPackets is a result of a query, so we need to use observer for + // the query to materialize model.allPackets.observe(this, { packets -> if (packets != null) { - saveMessagesCSV(file_uri, packets) + // no need for observer once got non-null list model.allPackets.removeObservers(this) + // execute on the default thread pool to not block the main thread + CoroutineScope(Dispatchers.Default + Job()).handledLaunch { + saveMessagesCSV(file_uri, packets) + } } }) } @@ -1084,11 +1088,8 @@ class MainActivity : AppCompatActivity(), Logging, } else if (my_position != null) { val dist: Int = positionToMeter(my_position!!, position).roundToInt() - fs.write( - ("${packet_proto.from.toUInt().toString(16)}," + - "${packet_proto.rxSnr},${packet_proto.rxTime},$dist\n") - .toByteArray() - ) + fs.write("%x,%f,%d,%d".format( packet_proto.from, + packet_proto.rxSnr, packet_proto.rxTime, dist).toByteArray()) } } } diff --git a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt b/app/src/main/java/com/geeksville/mesh/NodeInfo.kt index 77d26af77..2daeaeabd 100644 --- a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/NodeInfo.kt @@ -67,7 +67,8 @@ data class Position( data class NodeInfo( val num: Int, // This is immutable, and used as a key var user: MeshUser? = null, - var position: Position? = null + var position: Position? = null, + var snr: Float = 1000.0f ) : Parcelable { /// Return the last time we've seen this node in secs since 1970 diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 236c352e9..76fd3ca61 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -167,7 +167,7 @@ class MeshService : Service(), Logging { // FIXME - currently we don't support location reading without google play if (fusedLocationClient == null && isGooglePlayAvailable(this)) { GeeksvilleApplication.analytics.track("location_start") // Figure out how many users needed to use the phone GPS - + val request = LocationRequest.create().apply { interval = requestInterval priority = LocationRequest.PRIORITY_HIGH_ACCURACY @@ -713,6 +713,7 @@ class MeshService : Service(), Logging { // Handle new style position info Portnums.PortNum.POSITION_APP_VALUE -> { val u = MeshProtos.Position.parseFrom(data.payload) + debug("position_app ${packet.from} ${u.toOneLineString()}") handleReceivedPosition(packet.from, u, dataPacket.time) } @@ -820,6 +821,7 @@ class MeshService : Service(), Logging { defaultTime: Long = System.currentTimeMillis() ) { updateNodeInfo(fromNum) { + debug("update ${it.user?.longName} with ${p.toOneLineString()}") it.position = Position(p) updateNodeInfoTime(it, (defaultTime / 1000).toInt()) } @@ -916,6 +918,7 @@ class MeshService : Service(), Logging { updateNodeInfo(fromNum) { // Update our last seen based on any valid timestamps. If the device didn't provide a timestamp make one updateNodeInfoTime(it, rxTime) + it.snr = packet.rxSnr } handleReceivedData(packet) diff --git a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt index 0b6529679..db90c63f8 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt @@ -37,6 +37,7 @@ class UsersFragment : ScreenFragment("Users"), Logging { val batteryPctView = itemView.batteryPercentageView val lastTime = itemView.lastConnectionView val powerIcon = itemView.batteryIcon + val snrView = itemView.snrView } private val nodesAdapter = object : RecyclerView.Adapter() { @@ -115,10 +116,16 @@ class UsersFragment : ScreenFragment("Users"), Logging { } else { holder.distanceView.visibility = View.INVISIBLE } - + debug("node=${n.user?.longName} bat=${n.batteryPctLevel}") renderBattery(n.batteryPctLevel, holder) holder.lastTime.text = getLastTimeValue(n) + if ((n.num == ourNodeInfo?.num) || (n.snr > 100f)) { + holder.snrView.visibility = View.INVISIBLE + } else { + holder.snrView.visibility = View.VISIBLE + holder.snrView.text = n.snr.toString() + } } private var nodes = arrayOf() diff --git a/app/src/main/res/layout/adapter_node_layout.xml b/app/src/main/res/layout/adapter_node_layout.xml index 86d70f043..610eb0d60 100644 --- a/app/src/main/res/layout/adapter_node_layout.xml +++ b/app/src/main/res/layout/adapter_node_layout.xml @@ -71,6 +71,16 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/batteryIcon" /> + +