Developing Mobile Applications for Smart Agriculture (AgriTech)
A 100-hectare field is not an apartment with smart lights. Sensors are scattered across kilometers, cellular coverage is not everywhere, battery replacement once a year is a requirement, not a wish. Mobile applications for agro-IoT are built around several real constraints: low connectivity, long data cycles (every 15-60 minutes from LoRaWAN node), high cost of error (lost harvest).
IoT Protocols in Agriculture
LoRaWAN is the primary protocol for field sensors over large areas. Range up to 15 km in open field, milliwatt consumption, packets 51-222 bytes depending on Spreading Factor. LPWAN alternatives: NB-IoT (requires operator network but bidirectional), Sigfox (limited to 140 messages per day).
For greenhouses and infrastructure-equipped facilities — Zigbee/Thread, Wi-Fi, wired Modbus. For mobile assets (machinery, livestock) — GPRS/LTE with GPS tracker.
Data from LoRaWAN nodes flows through Network Server (TTN, ChirpStack, Helium) → Application Server → MQTT or REST → mobile application.
Data Architecture: Rare Updates, Rich Analytics
A LoRaWAN sensor updates data every 15-60 minutes. The mobile application shows not only current values but trends, anomalies, forecasts. This requires server aggregation and Time Series DB storage.
Data structure for soil sensor:
{
"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
}
}
On mobile side — Kotlin Flow with Room for offline work:
@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>>
}
Field Map and Zone Management
The key screen in agro-apps is a map with field polygons and sensor markers. On Flutter with flutter_map (Leaflet-based, free without API key) or 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',
// Or agro-layers: Sentinel-2 NDVI via 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 (vegetation index) comes from Sentinel-2 imagery via Copernicus Data Space API or Planet API. Images every 5-12 days in clear weather — automatically downloaded to backend and calculated per-pixel.
Alerts by Agro Thresholds
For agro-IoT, threshold alerts are critical: "Soil moisture below 25% in North-3 field" or "Frost expected by 04:00, 3 sensors show temperature below 2°C". Logic on backend, delivery via FCM/APNs.
A nuance for farmer notifications: phone is often in pocket during work, need brief informative texts. First line matters: "East field: moisture 18%, needs irrigation".
Offline Mode
LoRaWAN gateway on field may lack permanent internet. Some data syncs in batches when connection appears. Application shows "last update 2 hours ago" and doesn't panic. Critical to properly handle timestamps: sensor data has its own timestamp, which can differ significantly from server delivery time.
Developing agro-IoT application with field map, sensor monitoring and alerts for one crop: 2-3 months. Multi-crop monitoring, NDVI analytics, irrigation management and forecasts: 4-6 months. Cost calculated after analyzing sensor fleet and agronomy requirements.







