mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-03 19:27:24 +00:00
Even more restructuring and code cleanup
This commit is contained in:
1 parent
a807cfd8f6
commit
f8e7bcdf39
12 files changed
+222
-217
No files matched your search
@@ -8,21 +8,21 @@ import android.location.LocationManager
|
|||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import com.rtbishop.look4sat.data.DataParser
|
import com.rtbishop.look4sat.data.DataParser
|
||||||
import com.rtbishop.look4sat.data.DatabaseRepo
|
import com.rtbishop.look4sat.data.DatabaseRepo
|
||||||
|
import com.rtbishop.look4sat.data.ISensorSource
|
||||||
import com.rtbishop.look4sat.data.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.data.SelectionRepo
|
import com.rtbishop.look4sat.data.SelectionRepo
|
||||||
import com.rtbishop.look4sat.domain.IDatabaseRepo
|
import com.rtbishop.look4sat.domain.IDatabaseRepo
|
||||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.ISelectionRepo
|
import com.rtbishop.look4sat.domain.ISelectionRepo
|
||||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
|
||||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||||
import com.rtbishop.look4sat.framework.BluetoothReporter
|
import com.rtbishop.look4sat.framework.BluetoothReporter
|
||||||
import com.rtbishop.look4sat.framework.NetworkReporter
|
import com.rtbishop.look4sat.framework.NetworkReporter
|
||||||
import com.rtbishop.look4sat.framework.SensorsRepo
|
|
||||||
import com.rtbishop.look4sat.framework.SettingsRepo
|
import com.rtbishop.look4sat.framework.SettingsRepo
|
||||||
import com.rtbishop.look4sat.framework.data.DataSource
|
import com.rtbishop.look4sat.framework.data.DataSource
|
||||||
import com.rtbishop.look4sat.framework.data.LocalStorage
|
import com.rtbishop.look4sat.framework.data.LocalStorage
|
||||||
import com.rtbishop.look4sat.framework.data.MIGRATION_1_2
|
import com.rtbishop.look4sat.framework.data.MIGRATION_1_2
|
||||||
import com.rtbishop.look4sat.framework.data.MainDatabase
|
import com.rtbishop.look4sat.framework.data.MainDatabase
|
||||||
|
import com.rtbishop.look4sat.framework.data.SensorSource
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -40,7 +40,6 @@ class MainContainer(private val context: Context) {
|
|||||||
val databaseRepo = provideDatabaseRepo()
|
val databaseRepo = provideDatabaseRepo()
|
||||||
val satelliteRepo = provideSatelliteRepo()
|
val satelliteRepo = provideSatelliteRepo()
|
||||||
val selectionRepo = provideSelectionRepo()
|
val selectionRepo = provideSelectionRepo()
|
||||||
val sensorsRepo = provideSensorsRepo()
|
|
||||||
|
|
||||||
fun provideBluetoothReporter(): BluetoothReporter {
|
fun provideBluetoothReporter(): BluetoothReporter {
|
||||||
val btManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
val btManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
@@ -51,6 +50,12 @@ class MainContainer(private val context: Context) {
|
|||||||
return NetworkReporter(CoroutineScope(Dispatchers.IO))
|
return NetworkReporter(CoroutineScope(Dispatchers.IO))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun provideSensorSource(): ISensorSource {
|
||||||
|
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||||
|
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
||||||
|
return SensorSource(sensorManager, sensor)
|
||||||
|
}
|
||||||
|
|
||||||
private fun provideDatabaseRepo(): IDatabaseRepo {
|
private fun provideDatabaseRepo(): IDatabaseRepo {
|
||||||
val dataParser = DataParser(Dispatchers.Default)
|
val dataParser = DataParser(Dispatchers.Default)
|
||||||
val dataSource = DataSource(context.contentResolver, Dispatchers.IO)
|
val dataSource = DataSource(context.contentResolver, Dispatchers.IO)
|
||||||
@@ -58,19 +63,13 @@ class MainContainer(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun provideSatelliteRepo(): ISatelliteRepo {
|
private fun provideSatelliteRepo(): ISatelliteRepo {
|
||||||
return SatelliteRepo(Dispatchers.Default, localStorage)
|
return SatelliteRepo(Dispatchers.Default, localStorage, settingsRepo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun provideSelectionRepo(): ISelectionRepo {
|
private fun provideSelectionRepo(): ISelectionRepo {
|
||||||
return SelectionRepo(Dispatchers.Default, localStorage, settingsRepo)
|
return SelectionRepo(Dispatchers.Default, localStorage, settingsRepo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun provideSensorsRepo(): ISensorsRepo {
|
|
||||||
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
|
||||||
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
|
||||||
return SensorsRepo(sensorManager, sensor)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun provideSettingsRepo(): ISettingsRepo {
|
private fun provideSettingsRepo(): ISettingsRepo {
|
||||||
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
|
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.rtbishop.look4sat.domain.ISettingsRepo
|
|||||||
import com.rtbishop.look4sat.model.DatabaseState
|
import com.rtbishop.look4sat.model.DatabaseState
|
||||||
import com.rtbishop.look4sat.model.GeoPos
|
import com.rtbishop.look4sat.model.GeoPos
|
||||||
import com.rtbishop.look4sat.model.OtherSettings
|
import com.rtbishop.look4sat.model.OtherSettings
|
||||||
|
import com.rtbishop.look4sat.model.PassesSettings
|
||||||
import com.rtbishop.look4sat.utility.QthConverter
|
import com.rtbishop.look4sat.utility.QthConverter
|
||||||
import com.rtbishop.look4sat.utility.round
|
import com.rtbishop.look4sat.utility.round
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -99,15 +100,6 @@ class SettingsRepo(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadStationPosition(): GeoPos {
|
|
||||||
val latitude = (preferences.getString(keyLatitude, null) ?: "0.0").toDouble()
|
|
||||||
val longitude = (preferences.getString(keyLongitude, null) ?: "0.0").toDouble()
|
|
||||||
val altitude = (preferences.getString(keyAltitude, null) ?: "0.0").toDouble()
|
|
||||||
val qthLocator = preferences.getString(keyLocator, null) ?: "null"
|
|
||||||
val timestamp = preferences.getLong(keyLocTimestamp, 0L)
|
|
||||||
return GeoPos(latitude, longitude, altitude, qthLocator, timestamp)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveStationPosition(stationPos: GeoPos) = preferences.edit {
|
private fun saveStationPosition(stationPos: GeoPos) = preferences.edit {
|
||||||
putString(keyLatitude, stationPos.latitude.toString())
|
putString(keyLatitude, stationPos.latitude.toString())
|
||||||
putString(keyLongitude, stationPos.longitude.toString())
|
putString(keyLongitude, stationPos.longitude.toString())
|
||||||
@@ -126,8 +118,51 @@ class SettingsRepo(
|
|||||||
saveStationPosition(GeoPos(newLat, newLon, newAlt, locator, timestamp))
|
saveStationPosition(GeoPos(newLat, newLon, newAlt, locator, timestamp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadStationPosition(): GeoPos {
|
||||||
|
val latitude = (preferences.getString(keyLatitude, null) ?: "0.0").toDouble()
|
||||||
|
val longitude = (preferences.getString(keyLongitude, null) ?: "0.0").toDouble()
|
||||||
|
val altitude = (preferences.getString(keyAltitude, null) ?: "0.0").toDouble()
|
||||||
|
val qthLocator = preferences.getString(keyLocator, null) ?: "null"
|
||||||
|
val timestamp = preferences.getLong(keyLocTimestamp, 0L)
|
||||||
|
return GeoPos(latitude, longitude, altitude, qthLocator, timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region # Database update settings
|
||||||
|
|
||||||
|
private val _databaseState = MutableStateFlow(loadDatabaseState())
|
||||||
|
override val databaseState: StateFlow<DatabaseState> = _databaseState
|
||||||
|
|
||||||
|
override fun saveDatabaseState(state: DatabaseState) = preferences.edit {
|
||||||
|
putInt(keyDataEntries, state.entriesTotal)
|
||||||
|
putInt(keyDataRadios, state.radiosTotal)
|
||||||
|
putLong(keyDataTimestamp, state.timestamp)
|
||||||
|
_databaseState.value = state
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveSatType(type: String, catnums: List<Int>) {
|
||||||
|
val stringList = catnums.map { catnum -> catnum.toString() }
|
||||||
|
preferences.edit { putStringSet("type$type", stringList.toSet()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadSatType(type: String): List<Int> {
|
||||||
|
val catnums =
|
||||||
|
preferences.getStringSet("type$type", emptySet())?.map { catnum -> catnum.toInt() }
|
||||||
|
return catnums ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadDatabaseState(): DatabaseState {
|
||||||
|
val entriesTotal = preferences.getInt(keyDataEntries, 0)
|
||||||
|
val radiosTotal = preferences.getInt(keyDataRadios, 0)
|
||||||
|
val timestamp = preferences.getLong(keyDataTimestamp, 0L)
|
||||||
|
return DatabaseState(entriesTotal, radiosTotal, timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region # Entries selection settings
|
||||||
|
|
||||||
private val _satelliteSelection = MutableStateFlow(loadEntriesSelection())
|
private val _satelliteSelection = MutableStateFlow(loadEntriesSelection())
|
||||||
override val satelliteSelection: StateFlow<List<Int>> = _satelliteSelection
|
override val satelliteSelection: StateFlow<List<Int>> = _satelliteSelection
|
||||||
|
|
||||||
@@ -141,49 +176,36 @@ class SettingsRepo(
|
|||||||
return catNums?.map { catnum -> catnum.toInt() }?.sorted() ?: emptyList()
|
return catNums?.map { catnum -> catnum.toInt() }?.sorted() ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveSatType(type: String, catnums: List<Int>) {
|
//endregion
|
||||||
val stringList = catnums.map { catnum -> catnum.toString() }
|
|
||||||
preferences.edit { putStringSet("type$type", stringList.toSet()) }
|
//region # Passes filter settings
|
||||||
|
|
||||||
|
private val _passesSettings = MutableStateFlow(loadPassesSettings())
|
||||||
|
override val passesSettings: StateFlow<PassesSettings> = _passesSettings
|
||||||
|
|
||||||
|
override fun savePassesSettings(settings: PassesSettings) = preferences.edit {
|
||||||
|
putInt(keyHoursAhead, settings.hoursAhead)
|
||||||
|
putDouble(keyMinElevation, settings.minElevation)
|
||||||
|
_passesSettings.value = settings
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadSatType(type: String): List<Int> {
|
override fun saveModesSelection(modes: List<String>) {
|
||||||
val catnums =
|
preferences.edit { putStringSet(keyModes, modes.toSet()) }
|
||||||
preferences.getStringSet("type$type", emptySet())?.map { catnum -> catnum.toInt() }
|
|
||||||
return catnums ?: emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getHoursAhead(): Int {
|
override fun loadModesSelection(): List<String> {
|
||||||
return preferences.getInt(keyHoursAhead, 24)
|
return preferences.getStringSet(keyModes, null)?.toList()?.sorted() ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setHoursAhead(hoursAhead: Int) {
|
private fun loadPassesSettings(): PassesSettings {
|
||||||
preferences.edit { putInt(keyHoursAhead, hoursAhead) }
|
val hoursAhead = preferences.getInt(keyHoursAhead, 24)
|
||||||
|
val minElevation = preferences.getDouble(keyMinElevation, 16.0)
|
||||||
|
return PassesSettings(hoursAhead, minElevation)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMinElevation(): Double {
|
//endregion
|
||||||
return preferences.getDouble(keyMinElevation, 16.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setMinElevation(minElevation: Double) {
|
//region # Other settings
|
||||||
preferences.edit { putDouble(keyMinElevation, minElevation) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _databaseState = MutableStateFlow(loadDatabaseState())
|
|
||||||
override val databaseState: StateFlow<DatabaseState> = _databaseState
|
|
||||||
|
|
||||||
override fun saveDatabaseState(state: DatabaseState) = preferences.edit {
|
|
||||||
putInt(keyDataEntries, state.entriesTotal)
|
|
||||||
putInt(keyDataRadios, state.radiosTotal)
|
|
||||||
putLong(keyDataTimestamp, state.timestamp)
|
|
||||||
_databaseState.value = state
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadDatabaseState(): DatabaseState {
|
|
||||||
val entriesTotal = preferences.getInt(keyDataEntries, 0)
|
|
||||||
val radiosTotal = preferences.getInt(keyDataRadios, 0)
|
|
||||||
val timestamp = preferences.getLong(keyDataTimestamp, 0L)
|
|
||||||
return DatabaseState(entriesTotal, radiosTotal, timestamp)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _otherSettings = MutableStateFlow(loadOtherSettings())
|
private val _otherSettings = MutableStateFlow(loadOtherSettings())
|
||||||
override val otherSettings: StateFlow<OtherSettings> = _otherSettings
|
override val otherSettings: StateFlow<OtherSettings> = _otherSettings
|
||||||
@@ -216,13 +238,9 @@ class SettingsRepo(
|
|||||||
return OtherSettings(utcState, updateState, sweepState, sensorState)
|
return OtherSettings(utcState, updateState, sweepState, sensorState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveModesSelection(modes: List<String>) {
|
//endregion
|
||||||
preferences.edit { putStringSet(keyModes, modes.toSet()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadModesSelection(): List<String> {
|
//region # Undefined settings
|
||||||
return preferences.getStringSet(keyModes, null)?.toList()?.sorted() ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRotatorEnabled(): Boolean {
|
override fun getRotatorEnabled(): Boolean {
|
||||||
return preferences.getBoolean(keyRotator, false)
|
return preferences.getBoolean(keyRotator, false)
|
||||||
@@ -280,6 +298,8 @@ class SettingsRepo(
|
|||||||
preferences.edit { putString(keyBTFormat, value) }
|
preferences.edit { putString(keyBTFormat, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
private fun SharedPreferences.getDouble(key: String, default: Double): Double {
|
private fun SharedPreferences.getDouble(key: String, default: Double): Double {
|
||||||
return Double.fromBits(getLong(key, default.toRawBits()))
|
return Double.fromBits(getLong(key, default.toRawBits()))
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -15,30 +15,30 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.framework
|
package com.rtbishop.look4sat.framework.data
|
||||||
|
|
||||||
import android.hardware.Sensor
|
import android.hardware.Sensor
|
||||||
import android.hardware.SensorEvent
|
import android.hardware.SensorEvent
|
||||||
import android.hardware.SensorEventListener
|
import android.hardware.SensorEventListener
|
||||||
import android.hardware.SensorManager
|
import android.hardware.SensorManager
|
||||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
import com.rtbishop.look4sat.data.ISensorSource
|
||||||
import com.rtbishop.look4sat.domain.RAD2DEG
|
import com.rtbishop.look4sat.domain.RAD2DEG
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
|
|
||||||
class SensorsRepo(private val sensorManager: SensorManager, private val sensor: Sensor?) :
|
class SensorSource(private val sensorManager: SensorManager, private val sensor: Sensor?) :
|
||||||
SensorEventListener, ISensorsRepo {
|
SensorEventListener, ISensorSource {
|
||||||
|
|
||||||
private val rotationMatrix = FloatArray(9)
|
|
||||||
private val orientationValues = FloatArray(3)
|
|
||||||
private var sensorAccuracy: Int = SensorManager.SENSOR_STATUS_UNRELIABLE
|
|
||||||
|
|
||||||
private val _orientation = MutableStateFlow(Pair(0f, 0f))
|
private val _orientation = MutableStateFlow(Pair(0f, 0f))
|
||||||
|
private val rotationMatrix = FloatArray(9)
|
||||||
|
private val orientationValues = FloatArray(3)
|
||||||
|
private var sensorAccuracy = SensorManager.SENSOR_STATUS_UNRELIABLE
|
||||||
|
|
||||||
override val orientation: StateFlow<Pair<Float, Float>> = _orientation
|
override val orientation: StateFlow<Pair<Float, Float>> = _orientation
|
||||||
|
|
||||||
override fun enableSensor() {
|
override fun enableSensor() {
|
||||||
sensor?.let { sensorManager.registerListener(this, it, 16000) }
|
sensor?.let { sensorManager.registerListener(this, it, 8000) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun disableSensor() = sensorManager.unregisterListener(this)
|
override fun disableSensor() = sensorManager.unregisterListener(this)
|
||||||
@@ -57,12 +57,10 @@ class SensorsRepo(private val sensorManager: SensorManager, private val sensor:
|
|||||||
SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVector)
|
SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVector)
|
||||||
SensorManager.getOrientation(rotationMatrix, orientationValues)
|
SensorManager.getOrientation(rotationMatrix, orientationValues)
|
||||||
val azimuth = (orientationValues[0] * RAD2DEG).toFloat()
|
val azimuth = (orientationValues[0] * RAD2DEG).toFloat()
|
||||||
val pitch = (orientationValues[1] * RAD2DEG).toFloat()
|
val pitch = (orientationValues[1] * RAD2DEG).toFloat() // roll [2]
|
||||||
// val roll = (orientationValues[2] * RAD2DEG).toFloat()
|
|
||||||
val magneticAzimuth = (azimuth + 360f) % 360f
|
val magneticAzimuth = (azimuth + 360f) % 360f
|
||||||
val roundedAzimuth = round(magneticAzimuth * 10) / 10
|
val roundedAzimuth = round(magneticAzimuth * 10) / 10
|
||||||
val roundedPitch = round(pitch * 10) / 10
|
val roundedPitch = round(pitch * 10) / 10
|
||||||
// val roundedRoll = round(roll * 10) / 10
|
|
||||||
_orientation.value = Pair(roundedAzimuth, roundedPitch)
|
_orientation.value = Pair(roundedAzimuth, roundedPitch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,8 +49,8 @@ class MapViewModel(
|
|||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val stationPos = settingsRepo.stationPosition.value
|
private val stationPos = settingsRepo.stationPosition.value
|
||||||
private var allPasses = satelliteRepo.getPasses()
|
private var allPasses = satelliteRepo.passes.value
|
||||||
private var allSatellites = listOf<Satellite>()
|
private var allSatellites = satelliteRepo.satellites.value
|
||||||
private var dataUpdateJob: Job? = null
|
private var dataUpdateJob: Job? = null
|
||||||
private var dataUpdateRate = 1000L
|
private var dataUpdateRate = 1000L
|
||||||
private var selectedSatellite: Satellite? = null
|
private var selectedSatellite: Satellite? = null
|
||||||
@@ -87,18 +87,12 @@ class MapViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun selectDefaultSatellite(catnum: Int) {
|
fun selectDefaultSatellite(catnum: Int) {
|
||||||
viewModelScope.launch {
|
if (allSatellites.isNotEmpty()) {
|
||||||
val selectedIds = settingsRepo.satelliteSelection.value
|
if (catnum == -1) {
|
||||||
satelliteRepo.getEntriesWithIds(selectedIds).also { satellites ->
|
allPasses.find { pass -> pass.progress < 100 && !pass.isDeepSpace }
|
||||||
if (satellites.isNotEmpty()) {
|
?.let { pass -> selectSatellite(pass.satellite) }
|
||||||
allSatellites = satellites
|
} else {
|
||||||
if (catnum == -1) {
|
allSatellites.find { it.data.catnum == catnum }?.let { selectSatellite(it) }
|
||||||
allPasses.find { pass -> pass.progress < 100 && !pass.isDeepSpace }
|
|
||||||
?.let { pass -> selectSatellite(pass.satellite) }
|
|
||||||
} else {
|
|
||||||
satellites.find { it.data.catnum == catnum }?.let { selectSatellite(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,10 +53,9 @@ fun PassesScreen(navToRadar: (Int, Long) -> Unit) {
|
|||||||
val showDialog = rememberSaveable { mutableStateOf(false) }
|
val showDialog = rememberSaveable { mutableStateOf(false) }
|
||||||
val toggleDialog = { showDialog.value = showDialog.value.not() }
|
val toggleDialog = { showDialog.value = showDialog.value.not() }
|
||||||
if (showDialog.value) {
|
if (showDialog.value) {
|
||||||
FilterDialog(viewModel.getHoursAhead(),
|
val (hoursAhead, minElevation) = viewModel.getFilterSettings()
|
||||||
viewModel.getMinElevation(),
|
FilterDialog(hoursAhead, minElevation, { toggleDialog() }) { newHours, newElevation ->
|
||||||
{ toggleDialog() }) { hours, elev ->
|
viewModel.calculatePasses(System.currentTimeMillis(), newHours, newElevation)
|
||||||
viewModel.calculatePasses(hours, elev)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.rtbishop.look4sat.MainApplication
|
|||||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||||
import com.rtbishop.look4sat.model.DataState
|
import com.rtbishop.look4sat.model.DataState
|
||||||
|
import com.rtbishop.look4sat.model.PassesSettings
|
||||||
import com.rtbishop.look4sat.model.SatPass
|
import com.rtbishop.look4sat.model.SatPass
|
||||||
import com.rtbishop.look4sat.utility.toTimerString
|
import com.rtbishop.look4sat.utility.toTimerString
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -47,13 +48,14 @@ class PassesViewModel(
|
|||||||
val passes: StateFlow<DataState<List<SatPass>>> = _passes
|
val passes: StateFlow<DataState<List<SatPass>>> = _passes
|
||||||
val timerText: StateFlow<Triple<String, String, String>?> = _timerText
|
val timerText: StateFlow<Triple<String, String, String>?> = _timerText
|
||||||
|
|
||||||
fun getHoursAhead() = settingsRepo.getHoursAhead()
|
fun getFilterSettings() = settingsRepo.passesSettings.value
|
||||||
|
|
||||||
fun getMinElevation() = settingsRepo.getMinElevation()
|
fun shouldUseUTC() = settingsRepo.otherSettings.value.utcState
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
viewModelScope.launch { satelliteRepo.initRepository() }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
satelliteRepo.calculatedPasses.collect { passes ->
|
satelliteRepo.passes.collect { passes ->
|
||||||
passesProcessing?.cancelAndJoin()
|
passesProcessing?.cancelAndJoin()
|
||||||
passesProcessing = viewModelScope.launch {
|
passesProcessing = viewModelScope.launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
@@ -84,32 +86,20 @@ class PassesViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
|
||||||
settingsRepo.satelliteSelection.collect { calculatePasses() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldUseUTC() = settingsRepo.otherSettings.value.utcState
|
fun calculatePasses() = viewModelScope.launch {
|
||||||
|
_passes.emit(DataState.Loading)
|
||||||
|
passesProcessing?.cancelAndJoin()
|
||||||
|
val (hoursAhead, minElevation) = settingsRepo.passesSettings.value
|
||||||
|
satelliteRepo.calculatePasses(System.currentTimeMillis(), hoursAhead, minElevation)
|
||||||
|
}
|
||||||
|
|
||||||
fun calculatePasses(
|
fun calculatePasses(timeRef: Long, hoursAhead: Int, minElev: Double) = viewModelScope.launch {
|
||||||
hoursAhead: Int = 1,
|
_passes.emit(DataState.Loading)
|
||||||
minElevation: Double = settingsRepo.getMinElevation(),
|
passesProcessing?.cancelAndJoin()
|
||||||
timeRef: Long = System.currentTimeMillis()
|
settingsRepo.savePassesSettings(PassesSettings(hoursAhead, minElev))
|
||||||
) {
|
satelliteRepo.calculatePasses(timeRef, hoursAhead, minElev)
|
||||||
viewModelScope.launch {
|
|
||||||
_passes.emit(DataState.Loading)
|
|
||||||
// _timerText.postValue(timerDefaultText)
|
|
||||||
passesProcessing?.cancelAndJoin()
|
|
||||||
// selection?.let { items -> settingsRepository.saveEntriesSelection(items) }
|
|
||||||
settingsRepo.setHoursAhead(hoursAhead)
|
|
||||||
settingsRepo.setMinElevation(minElevation)
|
|
||||||
val stationPos = settingsRepo.stationPosition.value
|
|
||||||
val selectedIds = settingsRepo.satelliteSelection.value
|
|
||||||
val satellites = satelliteRepo.getEntriesWithIds(selectedIds)
|
|
||||||
satelliteRepo.calculatePasses(
|
|
||||||
satellites, stationPos, timeRef, hoursAhead, minElevation
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import androidx.lifecycle.viewmodel.initializer
|
import androidx.lifecycle.viewmodel.initializer
|
||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
import com.rtbishop.look4sat.MainApplication
|
import com.rtbishop.look4sat.MainApplication
|
||||||
|
import com.rtbishop.look4sat.data.ISensorSource
|
||||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
|
||||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||||
import com.rtbishop.look4sat.domain.Satellite
|
import com.rtbishop.look4sat.domain.Satellite
|
||||||
import com.rtbishop.look4sat.framework.BluetoothReporter
|
import com.rtbishop.look4sat.framework.BluetoothReporter
|
||||||
@@ -51,20 +51,20 @@ class RadarViewModel(
|
|||||||
private val networkReporter: NetworkReporter,
|
private val networkReporter: NetworkReporter,
|
||||||
private val satelliteRepo: ISatelliteRepo,
|
private val satelliteRepo: ISatelliteRepo,
|
||||||
private val settingsRepo: ISettingsRepo,
|
private val settingsRepo: ISettingsRepo,
|
||||||
private val sensorsRepo: ISensorsRepo
|
private val sensorSource: ISensorSource
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val stationPos = settingsRepo.stationPosition.value
|
private val stationPos = settingsRepo.stationPosition.value
|
||||||
private val magDeclination = getMagDeclination(stationPos)
|
private val magDeclination = getMagDeclination(stationPos)
|
||||||
val transmitters = mutableStateOf<List<SatRadio>>(emptyList())
|
val transmitters = mutableStateOf<List<SatRadio>>(emptyList())
|
||||||
val radarData = mutableStateOf<RadarData?>(null)
|
val radarData = mutableStateOf<RadarData?>(null)
|
||||||
val orientation = mutableStateOf(sensorsRepo.orientation.value)
|
val orientation = mutableStateOf(sensorSource.orientation.value)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (settingsRepo.otherSettings.value.sensorState) {
|
if (settingsRepo.otherSettings.value.sensorState) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
sensorsRepo.enableSensor()
|
sensorSource.enableSensor()
|
||||||
sensorsRepo.orientation.collect { data ->
|
sensorSource.orientation.collect { data ->
|
||||||
orientation.value = Pair(data.first + magDeclination, data.second)
|
orientation.value = Pair(data.first + magDeclination, data.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,29 +72,28 @@ class RadarViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
sensorsRepo.disableSensor()
|
sensorSource.disableSensor()
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPass() = flow {
|
fun getPass() = flow {
|
||||||
val catNum = savedStateHandle.get<Int>("catNum") ?: 0
|
val catNum = savedStateHandle.get<Int>("catNum") ?: 0
|
||||||
val aosTime = savedStateHandle.get<Long>("aosTime") ?: 0L
|
val aosTime = savedStateHandle.get<Long>("aosTime") ?: 0L
|
||||||
satelliteRepo.calculatedPasses.collect { passes ->
|
val passes = satelliteRepo.passes.value
|
||||||
val pass = passes.find { pass -> pass.catNum == catNum && pass.aosTime == aosTime }
|
val pass = passes.find { pass -> pass.catNum == catNum && pass.aosTime == aosTime }
|
||||||
val currentPass = pass ?: passes.firstOrNull()
|
val currentPass = pass ?: passes.firstOrNull()
|
||||||
currentPass?.let { satPass ->
|
currentPass?.let { satPass ->
|
||||||
emit(satPass)
|
emit(satPass)
|
||||||
val transmitters = satelliteRepo.getRadiosWithId(satPass.catNum)
|
val transmitters = satelliteRepo.getRadiosWithId(satPass.catNum)
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
val timeNow = System.currentTimeMillis()
|
val timeNow = System.currentTimeMillis()
|
||||||
val satPos =
|
val satPos =
|
||||||
satelliteRepo.getPosition(satPass.satellite, stationPos, timeNow)
|
satelliteRepo.getPosition(satPass.satellite, stationPos, timeNow)
|
||||||
sendPassData(satPass, satPos, satPass.satellite)
|
sendPassData(satPass, satPos, satPass.satellite)
|
||||||
sendPassDataBT(satPos)
|
sendPassDataBT(satPos)
|
||||||
processRadios(transmitters, satPass.satellite, timeNow)
|
processRadios(transmitters, satPass.satellite, timeNow)
|
||||||
delay(1000)
|
delay(1000)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +164,7 @@ class RadarViewModel(
|
|||||||
container.provideNetworkReporter(),
|
container.provideNetworkReporter(),
|
||||||
container.satelliteRepo,
|
container.satelliteRepo,
|
||||||
container.settingsRepo,
|
container.settingsRepo,
|
||||||
container.sensorsRepo
|
container.provideSensorSource()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package com.rtbishop.look4sat.domain
|
package com.rtbishop.look4sat.data
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface ISensorsRepo {
|
interface ISensorSource {
|
||||||
|
|
||||||
val orientation: StateFlow<Pair<Float, Float>>
|
val orientation: StateFlow<Pair<Float, Float>>
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
package com.rtbishop.look4sat.data
|
package com.rtbishop.look4sat.data
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||||
|
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||||
import com.rtbishop.look4sat.domain.Satellite
|
import com.rtbishop.look4sat.domain.Satellite
|
||||||
import com.rtbishop.look4sat.model.GeoPos
|
import com.rtbishop.look4sat.model.GeoPos
|
||||||
import com.rtbishop.look4sat.model.SatPass
|
import com.rtbishop.look4sat.model.SatPass
|
||||||
@@ -26,25 +27,33 @@ import com.rtbishop.look4sat.model.SatRadio
|
|||||||
import com.rtbishop.look4sat.utility.round
|
import com.rtbishop.look4sat.utility.round
|
||||||
import com.rtbishop.look4sat.utility.toDegrees
|
import com.rtbishop.look4sat.utility.toDegrees
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class SatelliteRepo(
|
class SatelliteRepo(
|
||||||
private val dispatcher: CoroutineDispatcher,
|
private val dispatcher: CoroutineDispatcher,
|
||||||
private val localStorage: ILocalStorage
|
private val localStorage: ILocalStorage,
|
||||||
|
private val settingsRepo: ISettingsRepo
|
||||||
) : ISatelliteRepo {
|
) : ISatelliteRepo {
|
||||||
|
|
||||||
private var passes = listOf<SatPass>()
|
private val _passes = MutableStateFlow<List<SatPass>>(emptyList())
|
||||||
private val _calculatedPasses = MutableSharedFlow<List<SatPass>>(replay = 1)
|
override val passes: StateFlow<List<SatPass>> = _passes
|
||||||
override val calculatedPasses: SharedFlow<List<SatPass>> = _calculatedPasses
|
|
||||||
|
|
||||||
override fun getPasses(): List<SatPass> = passes
|
private val _satellites = MutableStateFlow<List<Satellite>>(emptyList())
|
||||||
|
override val satellites: StateFlow<List<Satellite>> = _satellites
|
||||||
override suspend fun getEntriesWithIds(ids: List<Int>) = localStorage.getEntriesWithIds(ids)
|
|
||||||
|
|
||||||
override suspend fun getRadiosWithId(id: Int) = localStorage.getRadiosWithId(id)
|
override suspend fun getRadiosWithId(id: Int) = localStorage.getRadiosWithId(id)
|
||||||
|
|
||||||
|
override suspend fun initRepository() = withContext(dispatcher) {
|
||||||
|
settingsRepo.satelliteSelection.collect { selectedIds ->
|
||||||
|
_satellites.update { localStorage.getEntriesWithIds(selectedIds) }
|
||||||
|
val (hoursAhead, minElevation) = settingsRepo.passesSettings.value
|
||||||
|
calculatePasses(System.currentTimeMillis(), hoursAhead, minElevation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos {
|
override suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos {
|
||||||
return withContext(dispatcher) { sat.getPosition(pos, time) }
|
return withContext(dispatcher) { sat.getPosition(pos, time) }
|
||||||
}
|
}
|
||||||
@@ -70,12 +79,8 @@ class SatelliteRepo(
|
|||||||
val satPos = sat.getPosition(pos, time)
|
val satPos = sat.getPosition(pos, time)
|
||||||
val copiedList = radios.map { it.copy() }
|
val copiedList = radios.map { it.copy() }
|
||||||
copiedList.forEach { transmitter ->
|
copiedList.forEach { transmitter ->
|
||||||
transmitter.downlink?.let {
|
transmitter.downlink?.let { transmitter.downlink = satPos.getDownlinkFreq(it) }
|
||||||
transmitter.downlink = satPos.getDownlinkFreq(it)
|
transmitter.uplink?.let { transmitter.uplink = satPos.getUplinkFreq(it) }
|
||||||
}
|
|
||||||
transmitter.uplink?.let {
|
|
||||||
transmitter.uplink = satPos.getUplinkFreq(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
copiedList.map { it.copy() }
|
copiedList.map { it.copy() }
|
||||||
}
|
}
|
||||||
@@ -97,23 +102,18 @@ class SatelliteRepo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun calculatePasses(
|
override suspend fun calculatePasses(time: Long, hoursAhead: Int, minElevation: Double) {
|
||||||
satList: List<Satellite>, pos: GeoPos, time: Long, hoursAhead: Int, minElevation: Double
|
if (_satellites.value.isNotEmpty()) {
|
||||||
) {
|
|
||||||
if (satList.isEmpty()) {
|
|
||||||
val newPasses = emptyList<SatPass>()
|
|
||||||
passes = newPasses
|
|
||||||
_calculatedPasses.emit(newPasses)
|
|
||||||
} else {
|
|
||||||
withContext(dispatcher) {
|
withContext(dispatcher) {
|
||||||
val allPasses = mutableListOf<SatPass>()
|
val allPasses = mutableListOf<SatPass>()
|
||||||
satList.forEach { satellite ->
|
val stationPos = settingsRepo.stationPosition.value
|
||||||
allPasses.addAll(satellite.getPasses(pos, time, hoursAhead))
|
_satellites.value.forEach { satellite ->
|
||||||
|
allPasses.addAll(satellite.getPasses(stationPos, time, hoursAhead))
|
||||||
}
|
}
|
||||||
val newPasses = allPasses.filter(time, hoursAhead, minElevation)
|
_passes.update { allPasses.filter(time, hoursAhead, minElevation) }
|
||||||
passes = newPasses
|
|
||||||
_calculatedPasses.emit(newPasses)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_passes.update { emptyList() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +151,7 @@ class SatelliteRepo(
|
|||||||
private fun getGeoPass(sat: Satellite, pos: GeoPos, time: Long): SatPass {
|
private fun getGeoPass(sat: Satellite, pos: GeoPos, time: Long): SatPass {
|
||||||
val satPos = sat.getPosition(pos, time)
|
val satPos = sat.getPosition(pos, time)
|
||||||
val aos = time - 24 * 60L * 60L * 1000L
|
val aos = time - 24 * 60L * 60L * 1000L
|
||||||
val los = time + 24 * 60L * 60L * 1000L
|
val los = time + 24 * 60L * 60L * 1000L // val tca = (aos + los) / 2
|
||||||
// val tca = (aos + los) / 2
|
|
||||||
val az = satPos.azimuth.toDegrees().round(1)
|
val az = satPos.azimuth.toDegrees().round(1)
|
||||||
val elev = satPos.elevation.toDegrees().round(1)
|
val elev = satPos.elevation.toDegrees().round(1)
|
||||||
val alt = satPos.altitude
|
val alt = satPos.altitude
|
||||||
@@ -164,8 +163,7 @@ class SatelliteRepo(
|
|||||||
var calendarTimeMillis = time
|
var calendarTimeMillis = time
|
||||||
var elevation: Double
|
var elevation: Double
|
||||||
var maxElevation = 0.0
|
var maxElevation = 0.0
|
||||||
var alt = 0.0
|
var alt = 0.0 // var tcaAz = 0.0
|
||||||
// var tcaAz = 0.0
|
|
||||||
// rewind 1/4 of an orbit
|
// rewind 1/4 of an orbit
|
||||||
if (rewind) calendarTimeMillis += -quarterOrbitMin * 60L * 1000L
|
if (rewind) calendarTimeMillis += -quarterOrbitMin * 60L * 1000L
|
||||||
|
|
||||||
@@ -187,8 +185,7 @@ class SatelliteRepo(
|
|||||||
elevation = satPos.elevation
|
elevation = satPos.elevation
|
||||||
if (elevation > maxElevation) {
|
if (elevation > maxElevation) {
|
||||||
maxElevation = elevation
|
maxElevation = elevation
|
||||||
alt = satPos.altitude
|
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||||
// tcaAz = satPos.azimuth.toDegrees()
|
|
||||||
}
|
}
|
||||||
} while (satPos.elevation < 0.0)
|
} while (satPos.elevation < 0.0)
|
||||||
|
|
||||||
@@ -200,8 +197,7 @@ class SatelliteRepo(
|
|||||||
elevation = satPos.elevation
|
elevation = satPos.elevation
|
||||||
if (elevation > maxElevation) {
|
if (elevation > maxElevation) {
|
||||||
maxElevation = elevation
|
maxElevation = elevation
|
||||||
alt = satPos.altitude
|
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||||
// tcaAz = satPos.azimuth.toDegrees()
|
|
||||||
}
|
}
|
||||||
} while (satPos.elevation < 0.0)
|
} while (satPos.elevation < 0.0)
|
||||||
|
|
||||||
@@ -215,8 +211,7 @@ class SatelliteRepo(
|
|||||||
elevation = satPos.elevation
|
elevation = satPos.elevation
|
||||||
if (elevation > maxElevation) {
|
if (elevation > maxElevation) {
|
||||||
maxElevation = elevation
|
maxElevation = elevation
|
||||||
alt = satPos.altitude
|
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||||
// tcaAz = satPos.azimuth.toDegrees()
|
|
||||||
}
|
}
|
||||||
} while (satPos.elevation > 0.0)
|
} while (satPos.elevation > 0.0)
|
||||||
|
|
||||||
@@ -228,14 +223,12 @@ class SatelliteRepo(
|
|||||||
elevation = satPos.elevation
|
elevation = satPos.elevation
|
||||||
if (elevation > maxElevation) {
|
if (elevation > maxElevation) {
|
||||||
maxElevation = elevation
|
maxElevation = elevation
|
||||||
alt = satPos.altitude
|
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||||
// tcaAz = satPos.azimuth.toDegrees()
|
|
||||||
}
|
}
|
||||||
} while (satPos.elevation > 0.0)
|
} while (satPos.elevation > 0.0)
|
||||||
|
|
||||||
val los = satPos.time
|
val los = satPos.time // val tca = (aos + los) / 2
|
||||||
val losAz = satPos.azimuth.toDegrees().round(1)
|
val losAz = satPos.azimuth.toDegrees().round(1)
|
||||||
// val tca = (aos + los) / 2
|
|
||||||
val elev = maxElevation.toDegrees().round(1)
|
val elev = maxElevation.toDegrees().round(1)
|
||||||
return SatPass(aos, aosAz, los, losAz, alt.toInt(), elev, sat)
|
return SatPass(aos, aosAz, los, losAz, alt.toInt(), elev, sat)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,36 +4,27 @@ import com.rtbishop.look4sat.model.GeoPos
|
|||||||
import com.rtbishop.look4sat.model.SatPass
|
import com.rtbishop.look4sat.model.SatPass
|
||||||
import com.rtbishop.look4sat.model.SatPos
|
import com.rtbishop.look4sat.model.SatPos
|
||||||
import com.rtbishop.look4sat.model.SatRadio
|
import com.rtbishop.look4sat.model.SatRadio
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface ISatelliteRepo {
|
interface ISatelliteRepo {
|
||||||
|
|
||||||
val calculatedPasses: SharedFlow<List<SatPass>>
|
val passes: StateFlow<List<SatPass>>
|
||||||
|
|
||||||
fun getPasses(): List<SatPass>
|
val satellites: StateFlow<List<Satellite>>
|
||||||
|
|
||||||
suspend fun getEntriesWithIds(ids: List<Int>): List<Satellite>
|
|
||||||
|
|
||||||
suspend fun getRadiosWithId(id: Int): List<SatRadio>
|
suspend fun getRadiosWithId(id: Int): List<SatRadio>
|
||||||
|
|
||||||
|
suspend fun initRepository()
|
||||||
|
|
||||||
suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos
|
suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos
|
||||||
|
|
||||||
suspend fun getTrack(sat: Satellite, pos: GeoPos, start: Long, end: Long): List<SatPos>
|
suspend fun getTrack(sat: Satellite, pos: GeoPos, start: Long, end: Long): List<SatPos>
|
||||||
|
|
||||||
suspend fun processRadios(
|
suspend fun processRadios(
|
||||||
sat: Satellite,
|
sat: Satellite, pos: GeoPos, radios: List<SatRadio>, time: Long
|
||||||
pos: GeoPos,
|
|
||||||
radios: List<SatRadio>,
|
|
||||||
time: Long
|
|
||||||
): List<SatRadio>
|
): List<SatRadio>
|
||||||
|
|
||||||
suspend fun processPasses(passList: List<SatPass>, time: Long): List<SatPass>
|
suspend fun processPasses(passList: List<SatPass>, time: Long): List<SatPass>
|
||||||
|
|
||||||
suspend fun calculatePasses(
|
suspend fun calculatePasses(time: Long, hoursAhead: Int = 8, minElevation: Double = 16.0)
|
||||||
satList: List<Satellite>,
|
|
||||||
pos: GeoPos,
|
|
||||||
time: Long,
|
|
||||||
hoursAhead: Int = 8,
|
|
||||||
minElevation: Double = 16.0
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@@ -20,12 +20,12 @@ package com.rtbishop.look4sat.domain
|
|||||||
import com.rtbishop.look4sat.model.DatabaseState
|
import com.rtbishop.look4sat.model.DatabaseState
|
||||||
import com.rtbishop.look4sat.model.GeoPos
|
import com.rtbishop.look4sat.model.GeoPos
|
||||||
import com.rtbishop.look4sat.model.OtherSettings
|
import com.rtbishop.look4sat.model.OtherSettings
|
||||||
|
import com.rtbishop.look4sat.model.PassesSettings
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface ISettingsRepo {
|
interface ISettingsRepo {
|
||||||
|
|
||||||
val radioSourceUrl: String get() = "https://db.satnogs.org/api/transmitters/?format=json"
|
val radioSourceUrl: String get() = "https://db.satnogs.org/api/transmitters/?format=json"
|
||||||
|
|
||||||
val satelliteSourcesMap: Map<String, String>
|
val satelliteSourcesMap: Map<String, String>
|
||||||
get() = mapOf(
|
get() = mapOf(
|
||||||
"All" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
"All" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
||||||
@@ -56,9 +56,9 @@ interface ISettingsRepo {
|
|||||||
"X-Comm" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=x-comm&FORMAT=csv"
|
"X-Comm" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=x-comm&FORMAT=csv"
|
||||||
)
|
)
|
||||||
|
|
||||||
val stationPosition: StateFlow<GeoPos>
|
//region # Station position settings
|
||||||
|
|
||||||
val satelliteSelection: StateFlow<List<Int>>
|
val stationPosition: StateFlow<GeoPos>
|
||||||
|
|
||||||
fun setGpsPosition(): Boolean
|
fun setGpsPosition(): Boolean
|
||||||
|
|
||||||
@@ -66,18 +66,42 @@ interface ISettingsRepo {
|
|||||||
|
|
||||||
fun setQthPosition(locator: String): Boolean
|
fun setQthPosition(locator: String): Boolean
|
||||||
|
|
||||||
fun getHoursAhead(): Int
|
//endregion
|
||||||
|
|
||||||
fun setHoursAhead(hoursAhead: Int)
|
//region # Database update settings
|
||||||
|
|
||||||
fun getMinElevation(): Double
|
|
||||||
|
|
||||||
fun setMinElevation(minElevation: Double)
|
|
||||||
|
|
||||||
val databaseState: StateFlow<DatabaseState>
|
val databaseState: StateFlow<DatabaseState>
|
||||||
|
|
||||||
fun saveDatabaseState(state: DatabaseState)
|
fun saveDatabaseState(state: DatabaseState)
|
||||||
|
|
||||||
|
fun saveSatType(type: String, catnums: List<Int>)
|
||||||
|
|
||||||
|
fun loadSatType(type: String): List<Int>
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region # Entries selection settings
|
||||||
|
|
||||||
|
val satelliteSelection: StateFlow<List<Int>>
|
||||||
|
|
||||||
|
fun saveEntriesSelection(catnums: List<Int>)
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region # Passes filter settings
|
||||||
|
|
||||||
|
val passesSettings: StateFlow<PassesSettings>
|
||||||
|
|
||||||
|
fun savePassesSettings(settings: PassesSettings)
|
||||||
|
|
||||||
|
fun saveModesSelection(modes: List<String>)
|
||||||
|
|
||||||
|
fun loadModesSelection(): List<String>
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region # Other settings
|
||||||
|
|
||||||
val otherSettings: StateFlow<OtherSettings>
|
val otherSettings: StateFlow<OtherSettings>
|
||||||
|
|
||||||
fun toggleUtc(value: Boolean)
|
fun toggleUtc(value: Boolean)
|
||||||
@@ -88,15 +112,9 @@ interface ISettingsRepo {
|
|||||||
|
|
||||||
fun toggleSensor(value: Boolean)
|
fun toggleSensor(value: Boolean)
|
||||||
|
|
||||||
fun saveModesSelection(modes: List<String>)
|
//endregion
|
||||||
|
|
||||||
fun loadModesSelection(): List<String>
|
//region # Undefined settings
|
||||||
|
|
||||||
fun saveEntriesSelection(catnums: List<Int>)
|
|
||||||
|
|
||||||
fun saveSatType(type: String, catnums: List<Int>)
|
|
||||||
|
|
||||||
fun loadSatType(type: String): List<Int>
|
|
||||||
|
|
||||||
fun getRotatorEnabled(): Boolean
|
fun getRotatorEnabled(): Boolean
|
||||||
|
|
||||||
@@ -125,4 +143,6 @@ interface ISettingsRepo {
|
|||||||
fun getBTFormat(): String
|
fun getBTFormat(): String
|
||||||
|
|
||||||
fun setBTFormat(value: String)
|
fun setBTFormat(value: String)
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.rtbishop.look4sat.model
|
package com.rtbishop.look4sat.model
|
||||||
|
|
||||||
|
data class DatabaseState(val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long)
|
||||||
|
|
||||||
|
data class PassesSettings(val hoursAhead: Int, val minElevation: Double)
|
||||||
|
|
||||||
data class OtherSettings(
|
data class OtherSettings(
|
||||||
val utcState: Boolean,
|
val utcState: Boolean,
|
||||||
val updateState: Boolean,
|
val updateState: Boolean,
|
||||||
val sweepState: Boolean,
|
val sweepState: Boolean,
|
||||||
val sensorState: Boolean
|
val sensorState: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
data class DatabaseState(val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long)
|
|
||||||
Reference in new issue
Block a user