Налаштування пороговых значень IoT-датчиків через мобільний додаток
Пороговые значення — границі норми для датчика: вище +28°C — попередження, нижче +5°C — критично, відправити push. Користувач налаштовує ці границі у додатку, сервер зберігає їх та генерує алерти при виході за межі. Завдання виглядає просто, але потребує акуратного UX та надійної синхронізації з бекендом.
UI для налаштування порогів
Числові поля вводу — поганий вибір для порогів. Користувач не пам'ятає діапазон параметра, не бачить контексту. Краще — Range Slider з відображенням поточного значення датчика на тій же шкалі.
На Android Compose — користувацький RangeSlider або Slider з Material3. Стандартний RangeSlider з Material3 підтримує два ползунки:
var thresholds by remember { mutableStateOf(sensor.minThreshold..sensor.maxThreshold) }
Column {
Text("Температура: ${sensor.currentValue}°C")
Text("Допустимий діапазон: ${thresholds.start.roundToInt()}°C — ${thresholds.endInclusive.roundToInt()}°C")
RangeSlider(
value = thresholds,
onValueChange = { thresholds = it },
valueRange = sensor.absoluteMin..sensor.absoluteMax,
steps = 0,
onValueChangeFinished = {
viewModel.updateThresholds(sensor.id, thresholds.start, thresholds.endInclusive)
}
)
}
onValueChangeFinished — відправляти на сервер лише після відпускання ползунка, не при кожному русі. Інакше — шквал API-запитів при перетаскуванні.
Поточне значення датчика на шкалі слайдера — показати як вертикальну мітку. Через Canvas поверх слайдера: вичислити X-позицію по (currentValue - min) / (max - min) * sliderWidth.
Типи порогів
Різні параметри потребують різних конфігурацій:
| Параметр | Логіка | Приклад |
|---|---|---|
| Температура | Нижня + верхня границя | +5°C … +25°C |
| Рухи | Тільки булев триггер | Виявлено/ні |
| Рівень CO2 | Тільки верхня границя | > 1000 ppm |
| Тиск | Нижня + верхня + швидкість зміни | < 950 або > 1050 hPa |
Не намагатися зробити один універсальний компонент для всих. Краще набір спеціалізованих: BooleanThreshold, SingleBoundThreshold, RangeThreshold. Різні екрани налаштування для різних типів датчиків.
Синхронізація з сервером та локальний кеш
Пороги зберігаються на сервері та застосовуються на сервері при обробці телеметрії. Мобільний додаток — лише UI для налаштування.
При відкритті екрану: завантажити актуальні пороги з сервера, показати. При зміні: зберегти локально (оптимістичне оновлення), відправити на сервер, при помилці — откатить до попереднього значення.
fun updateThreshold(deviceId: String, min: Float, max: Float) {
val previous = _thresholds.value
// Оптимістичне оновлення
_thresholds.update { it.copy(minValue = min, maxValue = max) }
viewModelScope.launch {
val result = repository.saveThreshold(deviceId, min, max)
if (result.isFailure) {
// Відкат
_thresholds.value = previous
_events.emit(UiEvent.ShowError("Не вдалося зберегти налаштування"))
}
}
}
Оптимістичне оновлення робить UI відзивчивим — користувач не чекає відповіді сервера. Відкат — захист від втрати даних при мережевій помилці.
Повідомлення при перевищенні порога
Алерти приходять через push (FCM/APNS). Payload повідомлення має містити device_id, parameter, current_value, threshold_exceeded — щоб додаток міг відкрити потрібний екран при тапі на повідомлення.
На Android: setNotification() у FCM payload лише якщо додаток у фоні. Для foreground — FirebaseMessagingService.onMessageReceived() з локальним NotificationManager. Різні канали (NotificationChannel) для попереджень та критичних алертів — різні звуки та пріоритети.
Реалізація налаштування порогів з Range Slider, оптимістичним оновленням та push-алертами: 2–3 тижні. Стоимость рассчитывается индивидуально.







