минуты
This commit is contained in:
parent
54fb528400
commit
12df287193
|
|
@ -13,8 +13,8 @@ android {
|
||||||
applicationId "llc.arma.ble"
|
applicationId "llc.arma.ble"
|
||||||
minSdk 24
|
minSdk 24
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 8
|
versionCode 9
|
||||||
versionName "1.2.8"
|
versionName "1.2.9"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package llc.arma.ble.app.ui.screen.inspection.accelerometer.view
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -22,7 +23,10 @@ import llc.arma.ble.domain.model.BleInfo
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.Refresh
|
import androidx.compose.material.icons.rounded.Refresh
|
||||||
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.graphics.StrokeCap
|
import androidx.compose.ui.graphics.StrokeCap
|
||||||
|
import androidx.compose.ui.graphics.TransformOrigin
|
||||||
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import com.patrykandpatrick.vico.compose.axis.horizontal.bottomAxis
|
import com.patrykandpatrick.vico.compose.axis.horizontal.bottomAxis
|
||||||
import com.patrykandpatrick.vico.compose.chart.line.lineChart
|
import com.patrykandpatrick.vico.compose.chart.line.lineChart
|
||||||
|
|
@ -132,7 +136,6 @@ fun Display(
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val xProducer = remember {
|
val xProducer = remember {
|
||||||
ChartEntryModelProducer(listOf<FloatEntry>())
|
ChartEntryModelProducer(listOf<FloatEntry>())
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +154,9 @@ fun Display(
|
||||||
FloatEntry(index.toFloat(), measurePoint.x )
|
FloatEntry(index.toFloat(), measurePoint.x )
|
||||||
}
|
}
|
||||||
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
||||||
|
is MeasureData.Angle -> {
|
||||||
|
FloatEntry(index.toFloat(), measurePoint.xAngle )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -160,6 +166,9 @@ fun Display(
|
||||||
FloatEntry(index.toFloat(), measurePoint.y )
|
FloatEntry(index.toFloat(), measurePoint.y )
|
||||||
}
|
}
|
||||||
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
||||||
|
is MeasureData.Angle -> {
|
||||||
|
FloatEntry(index.toFloat(), measurePoint.yAngle )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -169,6 +178,9 @@ fun Display(
|
||||||
FloatEntry(index.toFloat(), measurePoint.z )
|
FloatEntry(index.toFloat(), measurePoint.z )
|
||||||
}
|
}
|
||||||
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
is MeasureData.Vibration -> FloatEntry(index.toFloat(), measurePoint.value)
|
||||||
|
is MeasureData.Angle -> {
|
||||||
|
FloatEntry(index.toFloat(), measurePoint.zAngle )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -180,7 +192,68 @@ fun Display(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(state.measureHistory.lastOrNull() is MeasureData.Accelerate) {
|
val lastMeasure = state.measureHistory.lastOrNull()
|
||||||
|
|
||||||
|
if(lastMeasure is MeasureData.Accelerate) {
|
||||||
|
|
||||||
|
if(state.mode == AccelViewMode.ANGLE){
|
||||||
|
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(text = "Ось X: ${lastMeasure.x}")
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Angle(
|
||||||
|
angle = lastMeasure.x,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(text = "Ось Y: ${lastMeasure.y}")
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Angle(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
angle = lastMeasure.y
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(text = "Ось Z: ${lastMeasure.z}")
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Angle(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
angle = lastMeasure.z
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
Column() {
|
Column() {
|
||||||
|
|
||||||
|
|
@ -241,6 +314,8 @@ fun Display(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
@ -274,6 +349,75 @@ fun Display(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Angle(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
angle: Float
|
||||||
|
) {
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
shape = CircleShape,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer
|
||||||
|
) {
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = modifier.padding(4.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(text = "0°C")
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier.weight(1f),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(text = "-90°C")
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.aspectRatio(1f)
|
||||||
|
.fillMaxHeight()
|
||||||
|
.padding(8.dp),
|
||||||
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
shape = CircleShape
|
||||||
|
) {
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier,
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.rotate(-90f + angle),
|
||||||
|
horizontalArrangement = Arrangement.End
|
||||||
|
) {
|
||||||
|
|
||||||
|
Box(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
Divider(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(text = "90°C")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(text = "±180°C")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Exception(
|
private fun Exception(
|
||||||
|
|
||||||
|
|
@ -324,6 +468,7 @@ class AccelerometerAccelContract {
|
||||||
sealed class State : ViewState {
|
sealed class State : ViewState {
|
||||||
|
|
||||||
data class Display(
|
data class Display(
|
||||||
|
val mode: AccelViewMode,
|
||||||
val measureHistory : List<MeasureData>
|
val measureHistory : List<MeasureData>
|
||||||
) : State()
|
) : State()
|
||||||
|
|
||||||
|
|
@ -349,7 +494,8 @@ class AccelerometerAccelViewModel @Inject constructor(
|
||||||
private var lastSerial: String? = null
|
private var lastSerial: String? = null
|
||||||
|
|
||||||
override fun setInitialState() = AccelerometerAccelContract.State.Display(
|
override fun setInitialState() = AccelerometerAccelContract.State.Display(
|
||||||
emptyList()
|
mode = AccelViewMode.ACCELERATION,
|
||||||
|
measureHistory = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun handleEvents(event: AccelerometerAccelContract.Event) {
|
override fun handleEvents(event: AccelerometerAccelContract.Event) {
|
||||||
|
|
@ -365,12 +511,14 @@ class AccelerometerAccelViewModel @Inject constructor(
|
||||||
event: AccelerometerAccelContract.Event.StopMeasure
|
event: AccelerometerAccelContract.Event.StopMeasure
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
measureJob?.cancel()
|
measureJob?.cancel()
|
||||||
measureJob = null
|
measureJob = null
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
AccelerometerAccelContract.State.Display(emptyList())
|
AccelerometerAccelContract.State.Display(
|
||||||
|
mode = AccelViewMode.ACCELERATION,
|
||||||
|
measureHistory = emptyList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +555,10 @@ class AccelerometerAccelViewModel @Inject constructor(
|
||||||
measureJob = viewModelScope.launch {
|
measureJob = viewModelScope.launch {
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
AccelerometerAccelContract.State.Display(emptyList())
|
AccelerometerAccelContract.State.Display(
|
||||||
|
mode = AccelViewMode.ACCELERATION,
|
||||||
|
measureHistory = emptyList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccelerometerMeasureBySerialFlow(serial, accelScale, accelMode, fftAxis, fftMode, frequency).onEach {
|
getAccelerometerMeasureBySerialFlow(serial, accelScale, accelMode, fftAxis, fftMode, frequency).onEach {
|
||||||
|
|
@ -422,11 +573,11 @@ class AccelerometerAccelViewModel @Inject constructor(
|
||||||
if(accelMode != AccelViewMode.ANGLE) {
|
if(accelMode != AccelViewMode.ANGLE) {
|
||||||
dataList = dataList.takeLast(10).toMutableList()
|
dataList = dataList.takeLast(10).toMutableList()
|
||||||
}
|
}
|
||||||
AccelerometerAccelContract.State.Display(dataList)
|
AccelerometerAccelContract.State.Display(accelMode, dataList)
|
||||||
}
|
}
|
||||||
|
|
||||||
AccelerometerAccelContract.State.Exception -> {
|
AccelerometerAccelContract.State.Exception -> {
|
||||||
AccelerometerAccelContract.State.Display(listOf(it))
|
AccelerometerAccelContract.State.Display(accelMode, listOf(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,21 +25,23 @@ fun IntervalEdit(
|
||||||
mutableStateOf((state.accelerometerState.historyInterval / 1000 / 60 / 60).toInt())
|
mutableStateOf((state.accelerometerState.historyInterval / 1000 / 60 / 60).toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
val maxInterval = 240
|
val maxInterval = 10 * 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
if(value > maxInterval){
|
if(value > maxInterval){
|
||||||
value = maxInterval
|
value = maxInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
if(value < 1){
|
if(value < 1){
|
||||||
value = 1
|
value = 1 * 60 * 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
val maxHours = maxInterval
|
val maxMinutes = maxInterval / millisInMinute
|
||||||
val maxDays = maxInterval / 24
|
val maxHours = maxInterval / millisInHour
|
||||||
|
val maxDays = maxInterval / millisInDay
|
||||||
|
|
||||||
val dayValue = value / 24
|
val dayValue = value / millisInDay
|
||||||
val hourValue = value - (24 * dayValue)
|
val hourValue = (value - (dayValue * millisInDay)) / millisInHour
|
||||||
|
val minutesValue = (value - (dayValue * millisInDay) - (hourValue * millisInHour)) / millisInMinute
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -62,7 +64,9 @@ fun IntervalEdit(
|
||||||
NumberPicker(
|
NumberPicker(
|
||||||
range = -1..maxDays,
|
range = -1..maxDays,
|
||||||
value = dayValue,
|
value = dayValue,
|
||||||
onValueChanged = { value = (it * 24) + hourValue }
|
onValueChanged = {
|
||||||
|
value = (it * millisInDay) + (hourValue * millisInHour) + (minutesValue * millisInMinute)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
@ -75,7 +79,7 @@ fun IntervalEdit(
|
||||||
range = -1..maxHours,
|
range = -1..maxHours,
|
||||||
value = hourValue,
|
value = hourValue,
|
||||||
onValueChanged = {
|
onValueChanged = {
|
||||||
value = it + (dayValue * 24)
|
value = (it * millisInHour) + (dayValue * millisInDay) + (minutesValue * millisInMinute)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -83,6 +87,20 @@ fun IntervalEdit(
|
||||||
|
|
||||||
Text(text = "Часы")
|
Text(text = "Часы")
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
|
NumberPicker(
|
||||||
|
range = -1..maxMinutes,
|
||||||
|
value = minutesValue,
|
||||||
|
onValueChanged = {
|
||||||
|
value = (it * millisInMinute) + (dayValue * millisInDay) + (hourValue * millisInHour)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
|
Text(text = "Минуты")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
@ -97,7 +115,7 @@ fun IntervalEdit(
|
||||||
onClick = {
|
onClick = {
|
||||||
onEvent(
|
onEvent(
|
||||||
AccelerometerContract.Event.OnSaveIntervalChanged(
|
AccelerometerContract.Event.OnSaveIntervalChanged(
|
||||||
value.toLong() * 1000 * 60 * 60
|
value.toLong()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +138,11 @@ fun IntervalEdit(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const val millisInMinute = 1000 * 60
|
||||||
|
const val millisInHour = millisInMinute * 60
|
||||||
|
const val millisInDay = millisInHour * 24
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NumberPicker(
|
fun NumberPicker(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,15 @@ enum class AccelScale(val k: Int) {
|
||||||
|
|
||||||
sealed class MeasureData {
|
sealed class MeasureData {
|
||||||
|
|
||||||
|
data class Angle(
|
||||||
|
val xAngle: Float,
|
||||||
|
val yAngle: Float,
|
||||||
|
val zAngle: Float,
|
||||||
|
val xAccelerate: Float,
|
||||||
|
val yAccelerate: Float,
|
||||||
|
val zAccelerate: Float,
|
||||||
|
) : MeasureData()
|
||||||
|
|
||||||
data class Accelerate(
|
data class Accelerate(
|
||||||
val x: Float,
|
val x: Float,
|
||||||
val y: Float,
|
val y: Float,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue