diff --git a/app/build.gradle b/app/build.gradle index 9305aeb..62ab741 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "llc.arma.ble" minSdk 24 targetSdk 33 - versionCode 8 - versionName "1.2.8" + versionCode 9 + versionName "1.2.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/AcceleromterAccel.kt b/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/AcceleromterAccel.kt index 71ea02d..ad72a1e 100644 --- a/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/AcceleromterAccel.kt +++ b/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/AcceleromterAccel.kt @@ -2,6 +2,7 @@ package llc.arma.ble.app.ui.screen.inspection.accelerometer.view import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -22,7 +23,10 @@ import llc.arma.ble.domain.model.BleInfo import javax.inject.Inject import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Refresh +import androidx.compose.ui.draw.rotate 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 com.patrykandpatrick.vico.compose.axis.horizontal.bottomAxis import com.patrykandpatrick.vico.compose.chart.line.lineChart @@ -132,7 +136,6 @@ fun Display( } else { - val xProducer = remember { ChartEntryModelProducer(listOf()) } @@ -151,6 +154,9 @@ fun Display( FloatEntry(index.toFloat(), measurePoint.x ) } 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 ) } 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 ) } 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( - 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) + 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() { + + 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:") - Chart( - chart = lineChart, - chartModelProducer = yProducer, - 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:") + Chart( + chart = lineChart, + chartModelProducer = yProducer, + 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 = "Ось Z:") - Chart( - chart = lineChart, - chartModelProducer = zProducer, - 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 = "Ось Z:") + Chart( + chart = lineChart, + chartModelProducer = zProducer, + 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) + ) ) - ) + + } } @@ -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 private fun Exception( @@ -324,6 +468,7 @@ class AccelerometerAccelContract { sealed class State : ViewState { data class Display( + val mode: AccelViewMode, val measureHistory : List ) : State() @@ -349,7 +494,8 @@ class AccelerometerAccelViewModel @Inject constructor( private var lastSerial: String? = null override fun setInitialState() = AccelerometerAccelContract.State.Display( - emptyList() + mode = AccelViewMode.ACCELERATION, + measureHistory = emptyList() ) override fun handleEvents(event: AccelerometerAccelContract.Event) { @@ -365,12 +511,14 @@ class AccelerometerAccelViewModel @Inject constructor( event: AccelerometerAccelContract.Event.StopMeasure ) { - measureJob?.cancel() measureJob = null setState { - AccelerometerAccelContract.State.Display(emptyList()) + AccelerometerAccelContract.State.Display( + mode = AccelViewMode.ACCELERATION, + measureHistory = emptyList() + ) } } @@ -407,7 +555,10 @@ class AccelerometerAccelViewModel @Inject constructor( measureJob = viewModelScope.launch { setState { - AccelerometerAccelContract.State.Display(emptyList()) + AccelerometerAccelContract.State.Display( + mode = AccelViewMode.ACCELERATION, + measureHistory = emptyList() + ) } getAccelerometerMeasureBySerialFlow(serial, accelScale, accelMode, fftAxis, fftMode, frequency).onEach { @@ -422,11 +573,11 @@ class AccelerometerAccelViewModel @Inject constructor( if(accelMode != AccelViewMode.ANGLE) { dataList = dataList.takeLast(10).toMutableList() } - AccelerometerAccelContract.State.Display(dataList) + AccelerometerAccelContract.State.Display(accelMode, dataList) } AccelerometerAccelContract.State.Exception -> { - AccelerometerAccelContract.State.Display(listOf(it)) + AccelerometerAccelContract.State.Display(accelMode, listOf(it)) } } } diff --git a/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/IntervalEdit.kt b/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/IntervalEdit.kt index 6a268d4..6d76677 100644 --- a/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/IntervalEdit.kt +++ b/app/src/main/java/llc/arma/ble/app/ui/screen/inspection/accelerometer/view/IntervalEdit.kt @@ -25,21 +25,23 @@ fun IntervalEdit( mutableStateOf((state.accelerometerState.historyInterval / 1000 / 60 / 60).toInt()) } - val maxInterval = 240 + val maxInterval = 10 * 24 * 60 * 60 * 1000 if(value > maxInterval){ value = maxInterval } if(value < 1){ - value = 1 + value = 1 * 60 * 1000 } - val maxHours = maxInterval - val maxDays = maxInterval / 24 + val maxMinutes = maxInterval / millisInMinute + val maxHours = maxInterval / millisInHour + val maxDays = maxInterval / millisInDay - val dayValue = value / 24 - val hourValue = value - (24 * dayValue) + val dayValue = value / millisInDay + val hourValue = (value - (dayValue * millisInDay)) / millisInHour + val minutesValue = (value - (dayValue * millisInDay) - (hourValue * millisInHour)) / millisInMinute Column( modifier = Modifier @@ -62,7 +64,9 @@ fun IntervalEdit( NumberPicker( range = -1..maxDays, value = dayValue, - onValueChanged = { value = (it * 24) + hourValue } + onValueChanged = { + value = (it * millisInDay) + (hourValue * millisInHour) + (minutesValue * millisInMinute) + } ) Spacer(modifier = Modifier.width(8.dp)) @@ -75,7 +79,7 @@ fun IntervalEdit( range = -1..maxHours, value = hourValue, onValueChanged = { - value = it + (dayValue * 24) + value = (it * millisInHour) + (dayValue * millisInDay) + (minutesValue * millisInMinute) } ) @@ -83,6 +87,20 @@ fun IntervalEdit( 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)) @@ -97,7 +115,7 @@ fun IntervalEdit( onClick = { onEvent( 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 fun NumberPicker( modifier: Modifier = Modifier, diff --git a/app/src/main/java/llc/arma/ble/domain/usecase/GetAccelerometerMeasureBySerialFlow.kt b/app/src/main/java/llc/arma/ble/domain/usecase/GetAccelerometerMeasureBySerialFlow.kt index 05c132f..814371c 100644 --- a/app/src/main/java/llc/arma/ble/domain/usecase/GetAccelerometerMeasureBySerialFlow.kt +++ b/app/src/main/java/llc/arma/ble/domain/usecase/GetAccelerometerMeasureBySerialFlow.kt @@ -35,6 +35,15 @@ enum class AccelScale(val k: Int) { 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( val x: Float, val y: Float,