ITSkillsCenter
Intelligence Artificielle

Dashboard agritech avec Grafana et SvelteKit : tutoriel 2026

11 min de lecture

📍 Article principal : Agritech IoT Afrique de l’Ouest 2026

Introduction

Pour la coopérative ouest-africaine du pilier, deux types d’utilisateurs consomment les données capteurs avec des besoins très différents. Les techniciens et agronomes veulent des dashboards riches avec graphiques détaillés, comparaisons inter-parcelles, analyses statistiques. Les agriculteurs ont besoin d’une vue ultra-simplifiée avec quelques indicateurs visuels et alertes claires. Servir ces deux audiences avec une seule interface est impossible — l’une est trop simple pour les techniciens, l’autre trop complexe pour les agriculteurs. La solution adoptée combine Grafana pour les techniciens et un dashboard SvelteKit personnalisé pour les agriculteurs, partageant la même base de données TimescaleDB en lecture. Ce tutoriel détaille la mise en œuvre complète : ingestion des données depuis MQTT, stockage TimescaleDB, dashboards Grafana avancés, frontend SvelteKit simplifié, et système d’alertes SMS pour les producteurs.

Prérequis

  • Serveur ChirpStack opérationnel exposant MQTT
  • VPS Hetzner CX22 ou CX32 disponible pour la stack dashboards
  • Connaissances de base SQL et SvelteKit
  • Compte Africa’s Talking ou Hubtel pour SMS d’alertes
  • Niveau : intermédiaire avancé — Temps : 4-6 heures

Étape 1 — Stockage TimescaleDB

TimescaleDB est l’extension PostgreSQL spécialisée pour les séries temporelles. Elle ajoute des fonctionnalités cruciales pour les données IoT : compression automatique, partitionnement par période, fonctions d’agrégation temporelles optimisées. Sur les données agritech (mesures capteurs régulières), TimescaleDB offre 10-20x les performances de PostgreSQL classique pour les requêtes analytiques tout en consommant 90 % moins d’espace disque grâce à la compression.

L’installation se fait via Docker à côté de la stack ChirpStack existante. Une seule instance TimescaleDB peut servir plusieurs applications (dashboard agritech, autres projets IoT) avec des bases distinctes. Le schéma initial pour les données agritech reste simple : une table mesures avec capteur_id, type_mesure, valeur, timestamp, transformée en hypertable pour bénéficier des optimisations TimescaleDB.

-- Création de la base et de la table principale
CREATE DATABASE agritech;
\c agritech
CREATE EXTENSION IF NOT EXISTS timescaledb;

CREATE TABLE mesures (
  capteur_id TEXT NOT NULL,
  type_mesure TEXT NOT NULL,
  valeur DOUBLE PRECISION NOT NULL,
  ts TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

SELECT create_hypertable('mesures', 'ts');
CREATE INDEX ON mesures (capteur_id, ts DESC);
CREATE INDEX ON mesures (type_mesure, ts DESC);

-- Politique de compression : compresser les données > 7 jours
ALTER TABLE mesures SET (timescaledb.compress, timescaledb.compress_segmentby = 'capteur_id, type_mesure');
SELECT add_compression_policy('mesures', INTERVAL '7 days');

Avec ce schéma et la politique de compression, TimescaleDB stocke efficacement plusieurs années de mesures dans un espace modeste. Pour 30 capteurs envoyant 4 mesures toutes les 15 minutes, on génère environ 12 000 mesures par jour, soit 4-5 millions par an. TimescaleDB compressé occupe quelques centaines de Mo seulement pour ce volume — largement contenu dans les 40 Go d’un VPS CX22.

Étape 2 — Ingestion MQTT vers TimescaleDB

Pour faire le pont entre ChirpStack (qui publie sur MQTT) et TimescaleDB (qui stocke les mesures), on développe un petit service ingester. Ce service souscrit aux topics MQTT pertinents, parse chaque message reçu, extrait les valeurs des capteurs, et les insère dans TimescaleDB. Un service Node.js de quelques dizaines de lignes suffit largement pour une coopérative de taille moyenne.

L’ingester tourne en permanence en tant que service systemd ou container Docker. En cas de coupure, il se reconnecte automatiquement à MQTT et reprend l’ingestion sans perte de données grâce au QoS MQTT 1 ou 2. Cette robustesse est essentielle pour des opérations 24/7 sur le terrain.

// ingester.ts (Node ou Bun)
import mqtt from 'mqtt';
import { Pool } from 'pg';

const pool = new Pool({ connectionString: process.env.DB_URL });
const client = mqtt.connect('mqtt://chirpstack:1883');

client.on('connect', () => {
  client.subscribe('application/+/device/+/event/up');
  console.log('Ingester ready');
});

client.on('message', async (topic, msg) => {
  try {
    const data = JSON.parse(msg.toString());
    const capteurId = data.deviceInfo.devEui;
    const decoded = data.object;
    if (!decoded) return;

    const insertions = Object.entries(decoded).map(([type, valeur]) =>
      pool.query('INSERT INTO mesures (capteur_id, type_mesure, valeur) VALUES ($1, $2, $3)', [capteurId, type, valeur])
    );
    await Promise.all(insertions);
  } catch (e) {
    console.error('Ingest error:', e);
  }
});

Avec cet ingester en place, chaque mesure capteur est automatiquement persistée dans TimescaleDB. Les applications dashboards consomment ensuite directement la base sans avoir à s’occuper de MQTT. Cette séparation entre ingestion et consultation simplifie radicalement l’architecture des applications front.

Étape 3 — Dashboard Grafana pour techniciens

Grafana est l’outil de visualisation de référence pour les séries temporelles. Riche en fonctionnalités, il offre des dashboards interactifs avec graphiques temporels, agrégations, filtrage par variables. Pour les techniciens et agronomes de la coopérative, Grafana donne accès à la richesse complète des données capteurs avec une interface professionnelle. L’installation Docker se fait en quelques minutes à côté de la stack existante.

Une fois Grafana installé, on configure TimescaleDB comme datasource (driver PostgreSQL standard) et on construit les dashboards. Pour un dashboard agritech type : graphique humidité du sol multi-parcelles avec filtre par parcelle, courbes pluviométrie/température sur la dernière semaine, gauges niveau batterie capteurs avec alertes visuelles, carte géolocalisée des capteurs avec statut online/offline. Les variables Grafana permettent aux utilisateurs de filtrer dynamiquement par parcelle ou période sans modifier le dashboard.

# Lancer Grafana avec persistance
docker run -d --name grafana \
  -p 3000:3000 \
  -v grafana-data:/var/lib/grafana \
  -e GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASS} \
  grafana/grafana

# Configurer TimescaleDB comme source dans Grafana
# Type: PostgreSQL
# Host: timescaledb:5432
# Database: agritech
# User: agritech_reader (créer un user read-only dédié)

Pour la sécurité, créer un utilisateur PostgreSQL en lecture seule dédié à Grafana plutôt qu’utiliser l’utilisateur admin. Cette séparation des privilèges suit le principe du moindre privilège. Pour l’authentification Grafana, intégrer SSO si la coopérative dispose déjà d’un Active Directory ou Keycloak — sinon les comptes locaux Grafana suffisent.

Étape 4 — Dashboard SvelteKit simplifié pour agriculteurs

L’interface agriculteur doit être radicalement différente. Une seule page qui affiche en grand les indicateurs critiques du jour. Pas de graphiques complexes, juste des feux verts/orange/rouge intuitifs. Pour le développement, SvelteKit permet de créer cette page personnalisée avec le ton, les couleurs, et la simplicité voulus. Le mobile-first est non négociable : 95 % des agriculteurs consultent depuis leur smartphone Tecno ou Itel d’entrée de gamme.

L’architecture est simple : SvelteKit côté serveur interroge TimescaleDB pour les dernières mesures de chaque parcelle, applique des règles métier pour déterminer le statut (irrigation nécessaire, alerte maladie, etc.), et envoie ces statuts au front. Le front rend une UI épurée optimisée pour des connexions lentes et des écrans de 4-5 pouces.

// +page.server.ts (SvelteKit)
export async function load({ params }) {
  const parcelle = params.id;
  const result = await db.query(`
    SELECT capteur_id, type_mesure, valeur, ts
    FROM mesures
    WHERE capteur_id IN (SELECT capteur_id FROM parcelle_capteurs WHERE parcelle_id = $1)
    ORDER BY ts DESC
    LIMIT 100
  `, [parcelle]);

  const dernieres = grouperParCapteur(result.rows);
  const statut = analyserStatut(dernieres);

  return { parcelle, statut, dernieres };
}

function analyserStatut(d) {
  if (d.humSol < 30) return { irrigation: 'rouge', message: 'Irrigation urgente' };
  if (d.humAir > 90 && d.tempAir > 25) return { maladie: 'orange', message: 'Risque mildiou' };
  return { ok: true, message: 'Tout va bien' };
}

L’interface affiche ensuite ces statuts en grand avec des couleurs intuitives. Pour les agriculteurs qui veulent creuser, un lien vers la version Grafana technique reste accessible — mais par défaut, la simplicité prime.

Étape 5 — Alertes SMS automatiques

Pour les agriculteurs qui n’ouvrent pas l’app au quotidien, les alertes SMS sont le canal universel. Un service de surveillance tourne périodiquement (toutes les 15-30 minutes) et envoie un SMS aux agriculteurs concernés quand un seuil est franchi. Pour limiter le spam SMS, ne déclencher que sur les alertes vraiment critiques et dédupliquer (ne pas envoyer le même SMS toutes les 15 minutes pour la même condition).

Pour l’intégration SMS, Africa’s Talking et Hubtel sont les références ouest-africaines avec API simple et tarifs raisonnables (5-15 FCFA par SMS selon pays et opérateurs). Pour les volumes importants, négocier un tarif dégressif via la commerciale. Pour éviter les abus, prévoir un quota mensuel par capteur ou par agriculteur — quelques dizaines de SMS suffisent largement pour les vraies alertes.

Erreurs fréquentes

Erreur Cause Solution
Grafana lent sur gros volumes TimescaleDB non compressé Activer compression policy après 7 jours
Ingester perd des messages QoS MQTT 0 par défaut Forcer QoS 1 dans le subscribe
SMS d’alerte spam Pas de déduplication Vérifier dernière alerte envoyée avant nouveau SMS
Dashboard agriculteur lent à charger Trop de données chargées initialement Limiter à 24h récentes, pagination si plus
Données manquantes périodiquement Capteur déchargé batterie Surveiller seuil batterie, alerter avant panne

Adaptation au contexte ouest-africain

Trois aspects pratiques. Premièrement, l’optimisation pour connexions lentes : minimiser les bundles JavaScript du dashboard agriculteur (moins de 100 Ko gzippés idéalement), images optimisées, lazy loading. Sur une connexion 4G saturée à Yopougon ou Pikine, ces optimisations font la différence entre une app utilisable et une app frustrante. Deuxièmement, l’internationalisation : supporter français standard plus langues locales selon zone (wolof, bambara, peul). Cette accessibilité linguistique élargit considérablement l’adoption. Troisièmement, le mode hors-ligne via service worker : permettre la consultation des dernières mesures cachées même sans connexion. PWA SvelteKit native cette fonctionnalité avec quelques lignes de code, et améliore considérablement l’expérience utilisateur ouest-africain.

Pour les coûts d’opération du stack dashboards complète (TimescaleDB, Grafana, ingester, SvelteKit), un VPS CX22 dédié à 5 euros par mois suffit largement pour servir 30-50 capteurs. Pour les déploiements plus importants, monter à CX32 reste très économique. Le coût SMS varie selon usage : pour 30 agriculteurs avec 5-10 alertes par mois, environ 2-5 euros mensuels.

Tutoriels frères

Pour aller plus loin

FAQ

Pourquoi pas Grafana directement pour les agriculteurs ?
Grafana est trop riche et complexe pour des utilisateurs non-techniques. L’interface dédiée SvelteKit reste indispensable pour l’adoption.

InfluxDB serait-il préférable à TimescaleDB ?
Les deux sont valables. TimescaleDB gagne par sa nature PostgreSQL : un seul système à apprendre, requêtes SQL standards, compatibilité avec les outils existants. Préférer pour démarrer.

Comment gérer les agriculteurs sans smartphone ?
Les alertes SMS suffisent pour le minimum vital. Pour le détail, prévoir des consultations imprimées hebdomadaires ou un référent local qui résume les statuts via WhatsApp aux groupes concernés.

Faut-il développer une vraie app native ?
PWA SvelteKit suffit dans 95 % des cas. Native uniquement si besoins spécifiques (notifications push fiables iOS, fonctionnalités hors-ligne avancées).

Patterns avancés et architecture multi-coopératives

Pour les structures qui servent plusieurs coopératives en parallèle, l’architecture multi-tenant devient pertinente. Le principe : une seule instance TimescaleDB et un seul serveur Grafana, mais une isolation logique stricte par coopérative via les schémas PostgreSQL ou les organisations Grafana. Chaque coopérative voit uniquement ses propres données et ses propres dashboards. Cette mutualisation infrastructure permet de servir 10-50 coopératives sur un seul VPS modeste, transformant l’économie du modèle.

Pour la sécurité multi-tenant, deux mesures essentielles. Premièrement, RLS (Row-Level Security) PostgreSQL qui filtre automatiquement les requêtes selon l’identité de l’utilisateur connecté. Cette protection au niveau base évite que les bugs applicatifs n’exposent les données d’une coopérative à une autre. Deuxièmement, audit log de toutes les requêtes pour traçabilité en cas d’incident. Pour une plateforme qui ambitionne de servir plusieurs dizaines de coopératives, ces patterns sont la base d’une architecture professionnelle.

Évolution et roadmap fonctionnelle

Une fois le dashboard de base stable, plusieurs évolutions naturelles enrichissent la valeur. L’ajout de prévisions météo via API (par exemple Open-Meteo gratuit) permet d’anticiper l’irrigation et les risques de maladies sur la prochaine semaine. L’intégration de l’imagerie satellite Sentinel-2 (gratuite via Copernicus) donne une vue NDVI complémentaire aux mesures sol. Le module export de rapports PDF mensuels facilite la communication avec les partenaires (bailleurs, banques agricoles, transformateurs). Chaque évolution ajoute typiquement 1-2 semaines de développement mais enrichit considérablement la valeur perçue par les coopératives.

Pour les agences techniques qui industrialisent leur offre, capitaliser ces évolutions dans des modules réutilisables d’un projet client à l’autre construit progressivement un produit SaaS exploitable au-delà du sur-mesure initial. Cette transition d’agence à produit est l’une des trajectoires de croissance les plus intéressantes pour les structures techniques ouest-africaines qui veulent dépasser le modèle prestation pure.

Cette stratégie de capitalisation progressive transforme un savoir-faire technique ponctuel en valeur récurrente sur la durée.

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité