Реалізація моніторингу почвених датчиків через мобільний додаток
Почвений датчик — звичайно Modbus RTU або SDI-12 на проводовому інтерфейсі, або LoRaWAN/NB-IoT для безпроводового. Популярні моделі: Sentek Drill & Drop (SDI-12), Vegetronix VH400 (аналоговий 0-3В), TEROS 12 (SDI-12), Decagon 5TM — всі з різними форматами виводу даних. Мобільний додаток отримує ці дані через IoT-шлюз або LoRaWAN Network Server — ніколи напрямку.
Що вимірює датчик та як інтерпретувати
Три основні параметри ґрунту:
VWC (Volumetric Water Content) — об'ємна вологість у відсотках. Значення 0-100%, на практиці для більшості ґрунтів робочий діапазон 10-40%. Датчик вимірює діелектричну проникність ґрунту, перерахунок у VWC — за формулою Топпа або за калібрувальними даними виробника для конкретного типу ґрунту.
EC (Electrical Conductivity) — електропровідність, мСм/см. Показує засоленість та концентрацію поживних речовин. Норма для більшості культур: 0,5-2,0 мСм/см. Вище 4 мСм/см — стрес для рослин.
Температура ґрунту — важлива для проростання насіння (більшість культур не проростають нижче 8-10°C) та активності мікроорганізмів.
Додаток повинен показувати не лише сирі значення, але й агрономічну інтерпретацію. «Вологість 19% при ПВ=45% для супіську» — це суходіл. Без контексту типу ґрунту та повної вологоємності (ПВ) число бессмисленне.
Отримання даних: LoRaWAN через ChirpStack
ChirpStack — open-source LoRaWAN Network та Application Server. REST API та gRPC інтерфейс:
// Kotlin, Retrofit для ChirpStack API
interface ChirpStackApi {
@GET("api/devices/{devEui}/events")
suspend fun getDeviceEvents(
@Header("Grpc-Metadata-Authorization") token: String,
@Path("devEui") devEui: String,
@Query("limit") limit: Int = 100,
): DeviceEventsResponse
}
data class DeviceEvent(
val publishedAt: String,
val data: String, // Base64-encoded payload
val rxInfo: List<RxInfo>,
)
fun decodePayload(base64Data: String): SoilReading {
val bytes = Base64.decode(base64Data, Base64.DEFAULT)
// Декодування залежить від кодування виробника датчика
// TEROS 12 Cayenne LPP формат:
val vwc = ((bytes[1].toInt() and 0xFF) shl 8 or (bytes[2].toInt() and 0xFF)) / 100.0
val temp = ((bytes[4].toInt() and 0xFF) shl 8 or (bytes[5].toInt() and 0xFF)) / 100.0 - 40
val ec = ((bytes[7].toInt() and 0xFF) shl 8 or (bytes[8].toInt() and 0xFF)) / 100.0
return SoilReading(vwc = vwc, temperature = temp, electricalConductivity = ec)
}
Для реального часу через MQTT — ChirpStack публікує події в топіки вида application/{appId}/device/{devEui}/event/up.
Дашборд: кілька датчиків на полі
Стандартна конфігурація — 3-5 датчиків на горизонти глибини (10, 30, 60, 90 см) в одній точці вимірювання. Дашборд показує профіль вологості за глибиною — вертикальний бар-чарт ефективніше звичайного списку:
Widget buildMoistureProfile(List<SoilLayerReading> layers) {
return Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
// Вісь глибини
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: layers.map((l) => Text('${l.depthCm} см')).toList(),
),
const SizedBox(width: 8),
Expanded(
child: Column(
children: layers.map((layer) {
final isLow = layer.vwc < layer.fieldCapacity * 0.5;
return Container(
margin: const EdgeInsets.symmetric(vertical: 2),
height: 32,
child: LinearProgressIndicator(
value: layer.vwc / 60.0, // нормуємо до 60% макс
backgroundColor: Colors.grey.shade200,
color: isLow ? Colors.orange : Colors.blue,
),
);
}).toList(),
),
),
],
),
);
}
Тренди та поріг поливу
Головна аналітична функція — показати момент, коли вологість опустилася до порога поливу (irrigation threshold), та коли повернулася до цільового рівня після поливу. Це допомагає агроному підтвердити, що система зрошення відпрацювала коректно.
График з fl_chart з горизонтальною лінією порога:
LineChartData buildTrendChart(List<SoilReading> readings, double threshold) {
return LineChartData(
extraLinesData: ExtraLinesData(
horizontalLines: [
HorizontalLine(
y: threshold,
color: Colors.orange,
strokeWidth: 1.5,
dashArray: [5, 5],
label: HorizontalLineLabel(
show: true,
labelResolver: (_) => 'Поріг поливу',
),
),
],
),
lineBarsData: [
LineChartBarData(
spots: readings
.map((r) => FlSpot(r.timestamp.toDouble(), r.vwc))
.toList(),
isCurved: true,
color: Colors.blue,
dotData: const FlDotData(show: false),
),
],
);
}
Алерти
Два типи алертів для почвених датчиків: за порогом вологості (нижче X% — потрібен полив) та за EC (вище Y мСм/см — ризик засолення). Доставка через FCM. Важливо: алерт за вологістю потрібно фільтрувати за часом доби та днями — якщо щойно пройшов дощ, алерт «потрібен полив» надлишковий. Backend повинен враховувати дані метеостанції або прогнозу погоди.
Розробка додатка моніторингу почвених датчиків з LoRaWAN-інтеграцією, профілями вологості та алертами: 3-5 тижнів. Вартість розраховується індивідуально.







