Разработка мобильного приложения для умного сельского хозяйства (Smart Agriculture)
Поле в 100 гектар — не квартира с умными лампочками. Датчики разбросаны на километры, GSM-связь есть не везде, батарейки менять раз в год — требование, а не пожелание. Мобильное приложение для агро-IoT строится вокруг нескольких реальных ограничений: низкая связность, длинные циклы данных (раз в 15-60 минут от LoRaWAN-узла), высокая стоимость ошибки (потерянный урожай).
Протоколы в агро-IoT
LoRaWAN — основной протокол для полевых датчиков на больших площадях. Диапазон до 15 км в открытом поле, потребление милливаты, пакеты 51-222 байта в зависимости от Spreading Factor. LPWAN-альтернативы: NB-IoT (нужна операторская сеть, зато двусторонняя связь), Sigfox (ограничение 140 сообщений в сутки).
Для теплиц и объектов с инфраструктурой — Zigbee/Thread, Wi-Fi, проводной Modbus. Для мобильных активов (техника, животные) — GPRS/LTE с GPS-трекером.
Данные с LoRaWAN-узлов идут через Network Server (TTN, ChirpStack, Helium) → Application Server → MQTT или REST → мобильное приложение.
Архитектура данных: редкие обновления, богатая аналитика
LoRaWAN-датчик обновляет данные каждые 15-60 минут. Мобильное приложение показывает не только текущие значения, но и тренды, аномалии, прогнозы. Это требует серверной агрегации и хранения в Time Series DB.
Структура данных для датчика почвы:
{
"deviceEui": "0004A30B001C3A4D",
"applicationId": "crop-monitoring-prod",
"timestamp": "2024-07-15T08:30:00Z",
"location": {"lat": 51.2345, "lon": 23.4567},
"payload": {
"soilMoistureVwc": 28.5,
"soilTemperatureC": 18.2,
"soilElectricalConductivity": 0.45,
"batteryPercent": 87,
"signalRssi": -98,
"snr": 4.2
}
}
На мобильной стороне — Kotlin Flow с roomdb для офлайн-работы:
@Dao
interface SensorReadingDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(readings: List<SensorReading>)
@Query("""
SELECT * FROM sensor_readings
WHERE device_eui = :eui
AND timestamp >= :from
ORDER BY timestamp DESC
""")
fun observeReadings(eui: String, from: Long): Flow<List<SensorReading>>
@Query("""
SELECT
CAST(strftime('%s', datetime(timestamp/1000, 'unixepoch', 'start of day')) AS INTEGER) * 1000 AS day,
AVG(soil_moisture_vwc) AS avg_moisture,
MIN(soil_temperature_c) AS min_temp,
MAX(soil_temperature_c) AS max_temp
FROM sensor_readings
WHERE device_eui = :eui
AND timestamp >= :from
GROUP BY day
ORDER BY day
""")
fun getDailyAggregates(eui: String, from: Long): Flow<List<DailyAggregate>>
}
Карта полей и зональное управление
Ключевой экран в агро-приложении — карта с полигонами полей и маркерами датчиков. На Flutter с flutter_map (Leaflet-based, бесплатно без API-key) или Google Maps:
class FieldMapWidget extends StatelessWidget {
final List<Field> fields;
final List<SensorDevice> sensors;
@override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(center: LatLng(51.23, 23.45), zoom: 13),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
// Или агро-слои: Sentinel-2 NDVI через EO Browser
),
PolygonLayer(
polygons: fields.map((f) => Polygon(
points: f.boundary,
color: _fieldColorByStatus(f),
borderColor: Colors.white,
borderStrokeWidth: 1.5,
)).toList(),
),
MarkerLayer(
markers: sensors.map((s) => Marker(
point: LatLng(s.lat, s.lon),
builder: (_) => SensorMarker(sensor: s),
)).toList(),
),
],
);
}
Color _fieldColorByStatus(Field field) {
final ndvi = field.latestNdvi;
if (ndvi == null) return Colors.grey.withOpacity(0.3);
if (ndvi < 0.3) return Colors.red.withOpacity(0.4);
if (ndvi < 0.5) return Colors.yellow.withOpacity(0.4);
return Colors.green.withOpacity(0.4);
}
}
NDVI (индекс вегетации) получают из Sentinel-2 снимков через Copernicus Data Space API или Planet API. Снимки раз в 5-12 дней при безоблачной погоде — автоматически скачиваются на бэкенд и рассчитываются попиксельно.
Уведомления по агро-порогам
Для агро-IoT критичны пороговые алерты: «Влажность почвы ниже 25% на поле Северный-3» или «Заморозок ожидается к 04:00, 3 датчика показывают температуру ниже 2°C». Логика на бэкенде, доставка через FCM/APNs.
Нюанс мобильных уведомлений для фермеров: телефон часто в кармане во время работы, нужны краткие информативные тексты без лишних слов. Первая строка уведомления — главное: «Поле Восток: влажность 18%, нужен полив».
Офлайн-режим
LoRaWAN шлюз на поле может не иметь постоянного интернета. Часть данных синхронизируется пачками при появлении связи. Приложение показывает «последнее обновление 2 часа назад» и не паникует. Критично правильно обрабатывать временны́е метки: данные с датчика имеют свой timestamp, который может сильно отличаться от времени доставки на сервер.
Разработка агро-IoT приложения с картой полей, мониторингом датчиков и алертами для одной культуры: 2-3 месяца. Многокультурный мониторинг, NDVI-аналитика, управление ирригацией и прогнозы — 4-6 месяцев. Стоимость рассчитывается после анализа парка датчиков и агрономических требований.







