feat: implement telemetry persistence, data visualization, and improved bluetooth stream parsing with frame statistics
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.example.esp32aldldashboard.data.database
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "sessions")
|
||||
data class SessionEntity(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val startTime: Long,
|
||||
val endTime: Long? = null,
|
||||
val name: String = "",
|
||||
val isSimulation: Boolean = false
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.example.esp32aldldashboard.data.database
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface TelemetryDao {
|
||||
|
||||
@Insert
|
||||
suspend fun insertSession(session: SessionEntity): Long
|
||||
|
||||
@Query("UPDATE sessions SET endTime = :endTime WHERE id = :sessionId")
|
||||
suspend fun endSession(sessionId: Long, endTime: Long)
|
||||
|
||||
@Insert
|
||||
suspend fun insertDataPoints(dataPoints: List<TelemetryDataPointEntity>)
|
||||
|
||||
@Query("SELECT * FROM sessions ORDER BY startTime DESC")
|
||||
fun getAllSessions(): Flow<List<SessionEntity>>
|
||||
|
||||
@Query("SELECT * FROM telemetry_data_points WHERE sessionId = :sessionId ORDER BY timestamp ASC")
|
||||
fun getSessionData(sessionId: Long): Flow<List<TelemetryDataPointEntity>>
|
||||
|
||||
@Query("DELETE FROM sessions WHERE id = :sessionId")
|
||||
suspend fun deleteSession(sessionId: Long)
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.example.esp32aldldashboard.data.database
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
tableName = "telemetry_data_points",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = SessionEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["sessionId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["sessionId", "timestamp"])
|
||||
]
|
||||
)
|
||||
data class TelemetryDataPointEntity(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val sessionId: Long,
|
||||
val timestamp: Long,
|
||||
val rawBytes: ByteArray
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as TelemetryDataPointEntity
|
||||
|
||||
if (id != other.id) return false
|
||||
if (sessionId != other.sessionId) return false
|
||||
if (timestamp != other.timestamp) return false
|
||||
return rawBytes.contentEquals(other.rawBytes)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + sessionId.hashCode()
|
||||
result = 31 * result + timestamp.hashCode()
|
||||
result = 31 * result + rawBytes.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.example.esp32aldldashboard.data.database
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
|
||||
@Database(entities = [SessionEntity::class, TelemetryDataPointEntity::class], version = 1, exportSchema = false)
|
||||
abstract class TelemetryDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun telemetryDao(): TelemetryDao
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE: TelemetryDatabase? = null
|
||||
|
||||
fun getDatabase(context: Context): TelemetryDatabase {
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
val instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
TelemetryDatabase::class.java,
|
||||
"telemetry_database"
|
||||
).build()
|
||||
INSTANCE = instance
|
||||
instance
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user