минуты

This commit is contained in:
Vineyro 2023-10-13 16:49:47 +07:00
parent 54fb528400
commit 12df287193
4 changed files with 251 additions and 68 deletions

View File

@ -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 {

View File

@ -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,64 +192,127 @@ fun Display(
) )
) )
if(state.measureHistory.lastOrNull() is MeasureData.Accelerate) { val lastMeasure = state.measureHistory.lastOrNull()
Column() { if(lastMeasure is MeasureData.Accelerate) {
Text(text = "Ось X:") if(state.mode == AccelViewMode.ANGLE){
Chart( Column(
chart = lineChart, verticalArrangement = Arrangement.spacedBy(16.dp),
chartModelProducer = xProducer, horizontalAlignment = Alignment.CenterHorizontally
startAxis = startAxis(), ) {
bottomAxis = bottomAxis(),
modifier = Modifier Column(
.fillMaxWidth() modifier = Modifier.weight(1f),
.weight(1f), horizontalAlignment = Alignment.CenterHorizontally
autoScaleUp = AutoScaleUp.None, ) {
diffAnimationSpec = tween(0),
chartScrollSpec = rememberChartScrollSpec( Text(text = "Ось X: ${lastMeasure.x}")
initialScroll = InitialScroll.End,
autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased, Spacer(modifier = Modifier.height(8.dp))
autoScrollAnimationSpec = tween(0)
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() {
Text(text = "Ось X:")
Chart(
chart = lineChart,
chartModelProducer = xProducer,
startAxis = startAxis(),
bottomAxis = bottomAxis(),
modifier = Modifier
.fillMaxWidth()
.weight(1f),
autoScaleUp = AutoScaleUp.None,
diffAnimationSpec = tween(0),
chartScrollSpec = rememberChartScrollSpec(
initialScroll = InitialScroll.End,
autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased,
autoScrollAnimationSpec = tween(0)
)
) )
)
Text(text = "Ось Y:") Text(text = "Ось Y:")
Chart( Chart(
chart = lineChart, chart = lineChart,
chartModelProducer = yProducer, chartModelProducer = yProducer,
startAxis = startAxis(), startAxis = startAxis(),
bottomAxis = bottomAxis(), bottomAxis = bottomAxis(),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),
autoScaleUp = AutoScaleUp.None, autoScaleUp = AutoScaleUp.None,
diffAnimationSpec = tween(0), diffAnimationSpec = tween(0),
chartScrollSpec = rememberChartScrollSpec( chartScrollSpec = rememberChartScrollSpec(
initialScroll = InitialScroll.End, initialScroll = InitialScroll.End,
autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased, autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased,
autoScrollAnimationSpec = tween(0) autoScrollAnimationSpec = tween(0)
)
) )
)
Text(text = "Ось Z:") Text(text = "Ось Z:")
Chart( Chart(
chart = lineChart, chart = lineChart,
chartModelProducer = zProducer, chartModelProducer = zProducer,
startAxis = startAxis(), startAxis = startAxis(),
bottomAxis = bottomAxis(), bottomAxis = bottomAxis(),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),
autoScaleUp = AutoScaleUp.None, autoScaleUp = AutoScaleUp.None,
diffAnimationSpec = tween(0), diffAnimationSpec = tween(0),
chartScrollSpec = rememberChartScrollSpec( chartScrollSpec = rememberChartScrollSpec(
initialScroll = InitialScroll.End, initialScroll = InitialScroll.End,
autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased, autoScrollCondition = AutoScrollCondition.OnModelSizeIncreased,
autoScrollAnimationSpec = tween(0) autoScrollAnimationSpec = tween(0)
)
) )
)
}
} }
@ -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))
} }
} }
} }

View File

@ -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,

View File

@ -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,