Aller au contenu

Tableaux de bord

Un tableau de bord IoT qui répond en 200 ms et affiche les bonnes métriques transforme un flux de données en outil de pilotage — la performance et la pertinence métier sont inséparables.


Grafana : l'écosystème de visualisation IoT

Grafana est devenu le standard de facto pour la visualisation des données IoT et DevOps. Sa force : un système de datasources qui permet d'interroger n'importe quelle source de données sans déplacer les données.

Datasources pertinentes pour l'IoT

Datasource Usage principal Protocole
InfluxDB Séries temporelles capteurs Flux / InfluxQL
TimescaleDB Séries temporelles + données relationnelles PostgreSQL wire
Prometheus Métriques infrastructure (broker, gateway) PromQL
Loki Logs centralisés (gateway, firmware) LogQL
Elasticsearch Recherche full-text sur événements ES Query DSL
MQTT Données temps réel (streaming panel) MQTT
Eclipse Ditto État des jumeaux numériques REST/HTTP

Architecture de déploiement Grafana

graph TB
    subgraph "Sources de données"
        INFLUX[(InfluxDB\nséries capteurs)]
        TIMESCALE[(TimescaleDB\ndonnées enrichies)]
        PROM[(Prometheus\nmétriques infra)]
        LOKI[(Loki\nlogs système)]
    end

    subgraph "Grafana Stack"
        GRAF[Grafana Server]
        AGENT[Grafana Agent\ncollecteur unifié]
        ALERT_MGR[Alertmanager]
        ONCALL[Grafana OnCall]
    end

    subgraph "Utilisateurs"
        OPS[Opérateurs terrain]
        MGMT[Direction / Management]
        MAINT[Maintenance]
    end

    INFLUX -->|Query| GRAF
    TIMESCALE -->|Query| GRAF
    PROM -->|PromQL| GRAF
    LOKI -->|LogQL| GRAF
    GRAF -->|Alertes| ALERT_MGR
    ALERT_MGR --> ONCALL
    ONCALL -->|SMS / Call| OPS
    ONCALL -->|Email| MGMT
    GRAF -->|Dashboard opérationnel| OPS
    GRAF -->|Dashboard KPIs| MGMT
    GRAF -->|Dashboard maintenance| MAINT
    AGENT -->|Scrape metrics| PROM
    AGENT -->|Collect logs| LOKI

Deux types de tableaux de bord

Dashboard opérationnel

Destiné aux opérateurs de terrain et aux techniciens de supervision. Exigences :

  • Rafraîchissement toutes les 5 à 30 secondes
  • Visualisation de l'état actuel (gauges, stat panels)
  • Alertes visuelles claires (rouge / orange / vert)
  • Navigation rapide entre équipements (variables de dashboard)
  • Pas plus de 20 panneaux par écran (lisibilité mur d'écrans)

Dashboard métier / KPIs

Destiné aux responsables de production et à la direction. Exigences :

  • Horizons temporels plus longs (jour / semaine / mois)
  • Agrégations métier (OEE, taux de disponibilité, consommation énergie/pièce)
  • Données comparatives (vs objectif, vs période précédente)
  • Export PDF planifié (rapport hebdomadaire automatique)
  • Rafraîchissement toutes les 5 à 15 minutes

Comparaison des panneaux selon le type

Type de panneau Opérationnel Métier
Gauge circulaire État instantané température Taux d'occupation global
Time series Courbe brute 1h capteur Tendance consommation 30j
Stat (valeur unique) Dernière mesure Production journalière
Bar chart Alarmes par zone Temps d'arrêt par ligne
Heatmap Corrélation temp/pression Répartition OEE mensuel
Table Liste alarmes actives Rapport d'incidents
Node graph Topologie équipements Flux entre ateliers

Requêtes optimisées pour les time-series

La performance des dashboards Grafana dépend en grande partie de la qualité des requêtes. Quelques règles fondamentales :

Règle 1 — Utiliser les pré-agrégations

Ne jamais interroger les données brutes sur un horizon long.

// ❌ Mauvais : 30 jours de données brutes (200 millions de points)
from(bucket: "iot_raw")
  |> range(start: -30d)
  |> filter(fn: (r) => r.device_id == "sensor-042")

// ✅ Bon : utiliser le bucket pré-agrégé 1h (17 520 points)
from(bucket: "iot_1hour")
  |> range(start: -30d)
  |> filter(fn: (r) => r.device_id == "sensor-042")

Règle 2 — Aligner la résolution sur la période d'affichage

Grafana passe $__interval comme variable de résolution automatique.

from(bucket: "iot_1min")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r.device_id == "${device_id}")
  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)

Équivalent TimescaleDB avec time_bucket_gapfill :

SELECT
    time_bucket_gapfill('${__interval}', time) AS bucket,
    device_id,
    interpolate(avg(value)) AS avg_value
FROM temperature_1min
WHERE
    time >= '${__from:date}' AND time < '${__to:date}'
    AND device_id = '${device_id}'
GROUP BY bucket, device_id
ORDER BY bucket;

Règle 3 — Variables de dashboard pour éviter les requêtes en boucle

-- Variable $site : liste des sites disponibles
SELECT DISTINCT site FROM device_metadata ORDER BY site;

-- Variable $device_id : filtrée par $site
SELECT device_id FROM device_metadata
WHERE site = '${site}'
ORDER BY device_id;

Les variables permettent de réutiliser un même dashboard pour 500 équipements sans dupliquer les panneaux.


Alerting Grafana

Grafana Alerting (depuis v9) centralise la gestion des alertes avec des règles définies directement dans l'interface.

Architecture alerting

flowchart LR
    subgraph "Évaluation"
        DS[(TimescaleDB\nInfluxDB)]
        RULE[Règle d'alerte\nEval every 1m\nFor 5m]
    end

    subgraph "Notification"
        AM[Alertmanager\nGrouping / Silencing]
        CP[Contact points\nEmail, PagerDuty\nSlack, Teams]
        NP[Notification policy\nRacinement par tag]
    end

    DS -->|Requête| RULE
    RULE -->|FIRING| AM
    AM --> NP
    NP --> CP

Exemple de règle d'alerte

# Fichier de provisioning Grafana (infrastructure as code)
apiVersion: 1
groups:
  - orgId: 1
    name: IoT Critical Alerts
    folder: IoT Production
    interval: 1m
    rules:
      - uid: temp_high_bearing
        title: "Température palier critique"
        condition: C
        data:
          - refId: A
            datasourceUid: influxdb_prod
            model:
              query: |
                from(bucket: "iot_1min")
                  |> range(start: -5m)
                  |> filter(fn: (r) => r._measurement == "temperature"
                      and r.sensor_type == "bearing")
                  |> mean()
          - refId: C
            datasourceUid: "__expr__"
            model:
              type: threshold
              conditions:
                - evaluator:
                    type: gt
                    params: [85]
                  query:
                    params: [A]
        for: 5m
        labels:
          severity: critical
          team: maintenance
        annotations:
          summary: "Palier surchauffé  {{$labels.device_id}}"
          description: "Température : {{$values.A.Text}}°C depuis 5 min"
          runbook_url: "https://wiki.example.com/runbooks/bearing-overheat"

Optimisation avancée : materialized views et pré-calcul

Pour les dashboards métier avec des calculs complexes (OEE, MTBF, consommation spécifique), pré-calculer les agrégats est indispensable.

OEE (Overall Equipment Effectiveness) en TimescaleDB

-- Vue matérialisée : OEE horaire par ligne de production
CREATE MATERIALIZED VIEW oee_hourly
WITH (timescaledb.continuous) AS
SELECT
    time_bucket('1 hour', time) AS hour,
    production_line,
    -- Disponibilité : temps de fonctionnement / temps planifié
    SUM(CASE WHEN state = 'RUNNING' THEN 1 ELSE 0 END)::float
        / COUNT(*) AS availability,
    -- Performance : cadence réelle / cadence nominale
    AVG(actual_rate / nominal_rate) AS performance,
    -- Qualité : pièces conformes / pièces produites
    SUM(good_parts)::float / NULLIF(SUM(total_parts), 0) AS quality,
    -- OEE = Disponibilité × Performance × Qualité
    (SUM(CASE WHEN state = 'RUNNING' THEN 1 ELSE 0 END)::float / COUNT(*))
        * AVG(actual_rate / nominal_rate)
        * (SUM(good_parts)::float / NULLIF(SUM(total_parts), 0)) AS oee
FROM production_metrics
GROUP BY hour, production_line;

Ce qu'il faut retenir

  • Séparer systématiquement les dashboards opérationnels (temps réel, opérateurs) des dashboards métier (tendances, KPIs, direction).
  • Toujours pointer vers les buckets pré-agrégés sur les horizons > 24h : la performance de Grafana dépend du volume de données retourné.
  • L'alerting Grafana unifié remplace avantageusement les alertes dispersées dans plusieurs outils.

Chapitre suivant : Intégration SI — connecter le pipeline IoT aux systèmes d'information de l'entreprise (ERP, MES, SCADA, datawarehouse).