Fixed transmitters doppler frequency update logic

pull/49/head
Arty Bishop 2021-04-05 19:32:07 +01:00
rodzic 555c2fe626
commit db710c55c4
7 zmienionych plików z 108 dodań i 90 usunięć
app
src/main/java/com/rtbishop/look4sat
fastlane/metadata/android/en-US
changelogs

Wyświetl plik

@ -13,8 +13,8 @@ android {
applicationId "com.rtbishop.look4sat"
minSdkVersion 21
targetSdkVersion 30
versionCode 231
versionName "2.3.1"
versionCode 232
versionName "2.3.2"
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")

Wyświetl plik

@ -26,8 +26,8 @@ data class SatTrans(
@PrimaryKey @field:Json(name = "uuid") val uuid: String,
@field:Json(name = "description") val info: String,
@field:Json(name = "alive") val isAlive: Boolean,
@field:Json(name = "downlink_low") val downlink: Long?,
@field:Json(name = "uplink_low") val uplink: Long?,
@field:Json(name = "downlink_low") var downlink: Long?,
@field:Json(name = "uplink_low") var uplink: Long?,
@field:Json(name = "mode") val mode: String?,
@field:Json(name = "invert") val isInverted: Boolean,
@field:Json(name = "norad_cat_id") val catNum: Int

Wyświetl plik

@ -40,17 +40,18 @@ class PolarFragment : Fragment(R.layout.fragment_polar) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentPolarBinding.bind(view)
val catNum = requireArguments().getInt("catNum")
val aosTime = requireArguments().getLong("aosTime")
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
polarView = PolarView(requireContext()).apply { setPass(pass) }
binding.frame.addView(polarView)
observeTransmitters(pass, binding)
FragmentPolarBinding.bind(view).apply {
val transAdapter = TransAdapter()
recycler.apply {
setHasFixedSize(true)
adapter = transAdapter
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
}
setupObservers(transAdapter, this)
}
viewModel.azimuth.observe(viewLifecycleOwner, { trueNorthAzimuth ->
polarView?.rotation = -trueNorthAzimuth
})
}
override fun onResume() {
@ -63,35 +64,41 @@ class PolarFragment : Fragment(R.layout.fragment_polar) {
viewModel.disableSensor()
}
private fun observeTransmitters(satPass: SatPass, binding: FragmentPolarBinding) {
viewModel.getSatTransmitters(satPass.catNum).observe(viewLifecycleOwner, { list ->
val transmitterAdapter = TransAdapter(satPass)
private fun setupObservers(transAdapter: TransAdapter, binding: FragmentPolarBinding) {
val catNum = requireArguments().getInt("catNum")
val aosTime = requireArguments().getLong("aosTime")
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
polarView = PolarView(requireContext()).apply { setPass(pass) }
binding.frame.addView(polarView)
observeTransmitters(pass, transAdapter, binding)
}
viewModel.azimuth.observe(viewLifecycleOwner, { trueNorthAzimuth ->
polarView?.rotation = -trueNorthAzimuth
})
}
private fun observeTransmitters(
satPass: SatPass,
transAdapter: TransAdapter,
binding: FragmentPolarBinding
) {
viewModel.transmitters.observe(viewLifecycleOwner, { list ->
if (list.isNotEmpty()) {
transmitterAdapter.setData(list)
binding.recycler.apply {
setHasFixedSize(true)
adapter = transmitterAdapter
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
visibility = View.VISIBLE
}
transAdapter.submitList(list)
binding.recycler.visibility = View.VISIBLE
binding.noTransMsg.visibility = View.INVISIBLE
} else {
binding.recycler.visibility = View.INVISIBLE
binding.noTransMsg.visibility = View.VISIBLE
}
viewModel.getAppTimer().observe(viewLifecycleOwner, {
setPassText(it, satPass, binding)
polarView?.invalidate()
transmitterAdapter.tickTransmitters()
})
setPassText(satPass, binding)
polarView?.invalidate()
})
}
private fun setPassText(timeNow: Long, satPass: SatPass, binding: FragmentPolarBinding) {
val dateNow = Date(timeNow)
private fun setPassText(satPass: SatPass, binding: FragmentPolarBinding) {
val dateNow = Date()
val timeNow = System.currentTimeMillis()
val satPos = satPass.predictor.getSatPos(dateNow)
val polarAz = getString(R.string.pat_azimuth)
val polarEl = getString(R.string.pat_elevation)

Wyświetl plik

@ -18,12 +18,18 @@
package com.rtbishop.look4sat.ui.polarScreen
import androidx.lifecycle.*
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SatTrans
import com.rtbishop.look4sat.data.repository.PassesRepo
import com.rtbishop.look4sat.data.repository.SatelliteRepo
import com.rtbishop.look4sat.utility.PrefsManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.util.*
import javax.inject.Inject
@HiltViewModel
@ -35,20 +41,18 @@ class PolarViewModel @Inject constructor(
) : ViewModel(), Orientation.OrientationListener {
private val magDeclination = prefsManager.getMagDeclination()
private val _transmitters = MutableLiveData<List<SatTrans>>()
private val _azimuth = MutableLiveData<Float>()
val transmitters: LiveData<List<SatTrans>> = _transmitters
val azimuth: LiveData<Float> = _azimuth
fun getAppTimer() = liveData {
while (true) {
emit(System.currentTimeMillis())
delay(1000)
}
}
fun getPass(catNum: Int, aosTime: Long) = liveData {
passesRepo.passes.collect { passes ->
val pass = passes.find { it.catNum == catNum && it.aosDate.time == aosTime }
pass?.let { emit(it) }
pass?.let { satPass ->
processTransmitters(satPass)
emit(satPass)
}
}
}
@ -60,10 +64,28 @@ class PolarViewModel @Inject constructor(
if (prefsManager.shouldUseCompass()) orientation.stopListening()
}
fun getSatTransmitters(satId: Int) =
satelliteRepo.getSatTransmitters(satId).asLiveData(viewModelScope.coroutineContext)
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
_azimuth.value = azimuth + magDeclination
}
private fun processTransmitters(satPass: SatPass) {
viewModelScope.launch {
satelliteRepo.getSatTransmitters(satPass.catNum).collect { transList ->
while (isActive) {
val timeNow = Date()
val copiedList = transList.map { it.copy() }
copiedList.forEach { transmitter ->
transmitter.downlink?.let {
transmitter.downlink = satPass.predictor.getDownlinkFreq(it, timeNow)
}
transmitter.uplink?.let {
transmitter.uplink = satPass.predictor.getUplinkFreq(it, timeNow)
}
}
_transmitters.postValue(copiedList.map { it.copy() })
delay(1000)
}
}
}
}
}

Wyświetl plik

@ -19,45 +19,44 @@ package com.rtbishop.look4sat.ui.polarScreen
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SatTrans
import com.rtbishop.look4sat.databinding.ItemTransBinding
import com.rtbishop.look4sat.utility.PassPredictor
import java.util.*
class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapter.TransHolder>() {
class TransAdapter : RecyclerView.Adapter<TransAdapter.TransHolder>() {
private var transmittersList = emptyList<SatTrans>()
private val diffCallback = object : DiffUtil.ItemCallback<SatTrans>() {
override fun areItemsTheSame(oldItem: SatTrans, newItem: SatTrans): Boolean {
return oldItem.uuid == newItem.uuid
}
fun setData(list: List<SatTrans>) {
transmittersList = list
notifyDataSetChanged()
}
fun tickTransmitters() {
if (!pass.isDeepSpace) {
notifyDataSetChanged()
override fun areContentsTheSame(oldItem: SatTrans, newItem: SatTrans): Boolean {
return oldItem.downlink == newItem.downlink
}
}
private val differ = AsyncListDiffer(this, diffCallback)
override fun getItemCount(): Int {
return transmittersList.size
fun submitList(transmitters: List<SatTrans>) {
differ.submitList(transmitters)
}
override fun getItemCount() = differ.currentList.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransHolder {
return TransHolder.from(parent)
}
override fun onBindViewHolder(holder: TransHolder, position: Int) {
holder.bind(transmittersList[position], pass)
holder.bind(differ.currentList[position])
}
class TransHolder private constructor(private val binding: ItemTransBinding) :
RecyclerView.ViewHolder(binding.root) {
private val dateNow = Date()
private val divider = 1000000f
private val strNo = itemView.context.getString(R.string.btn_no)
private val strYes = itemView.context.getString(R.string.btn_yes)
@ -66,11 +65,22 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
private val formatLinkNull = itemView.context.getString(R.string.trans_no_link)
private val isInverted = itemView.context.getString(R.string.trans_inverted)
fun bind(satTrans: SatTrans, satPass: SatPass) {
fun bind(satTrans: SatTrans) {
binding.description.text = satTrans.info
if (satPass.isDeepSpace) setRegularFreq(satTrans)
else setDopplerFreq(satTrans, satPass.predictor)
satTrans.downlink.let { downlink ->
if (downlink != null) {
val downlinkFreq = downlink / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downlinkFreq)
} else binding.downlink.text = formatLinkNull
}
satTrans.uplink.let { uplink ->
if (uplink != null) {
val uplinkFreq = uplink / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, uplinkFreq)
} else binding.uplink.text = formatLinkNull
}
if (satTrans.mode != null) binding.mode.text = String.format(mode, satTrans.mode)
else binding.mode.text = String.format(mode, strNo)
@ -79,30 +89,6 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
else binding.isInverted.text = String.format(isInverted, strNo)
}
private fun setRegularFreq(satTrans: SatTrans) {
if (satTrans.downlink != null) {
val downFreq = satTrans.downlink / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downFreq)
} else binding.downlink.text = formatLinkNull
if (satTrans.uplink != null) {
val upFreq = satTrans.uplink / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, upFreq)
} else binding.uplink.text = formatLinkNull
}
private fun setDopplerFreq(satTrans: SatTrans, predictor: PassPredictor) {
if (satTrans.downlink != null) {
val downlink = predictor.getDownlinkFreq(satTrans.downlink, dateNow) / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downlink)
} else binding.downlink.text = formatLinkNull
if (satTrans.uplink != null) {
val uplink = predictor.getUplinkFreq(satTrans.uplink, dateNow) / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, uplink)
} else binding.uplink.text = formatLinkNull
}
companion object {
fun from(parent: ViewGroup): TransHolder {
val inflater = LayoutInflater.from(parent.context)

Wyświetl plik

@ -3,4 +3,6 @@ Now updating recyclers views asyncronously
Switched to concurrent satellite data update
Minor visual changes to map info
Separated application screens logic
Bug fixes, huge code cleanup
Bug fixes, huge code cleanup
Fixed recent InflatingException
Fixed transmitters doppler frequency update logic

Wyświetl plik

@ -4,4 +4,5 @@ Switched to concurrent satellite data update
Minor visual changes to map info
Separated application screens logic
Bug fixes, huge code cleanup
Fixed recent InflatingException
Fixed recent InflatingException
Fixed transmitters doppler frequency update logic