Construire un systeme de suivi d’actifs avec BLE tag ne consiste pas a choisir la bonne etiquette. Il s’agit de l’infrastructure qui recoit, filtre, transporte et stocke les donnees de centaines ou milliers d’etiquettes dispersées dans une installation. L’etiquette est un emetteur simple ; l’intelligence reside dans le reseau de passerelles, le processeur edge et le backend cloud. Cet article decompose l’architecture complete du systeme, de la reception radio au tableau de bord, avec des tableaux de selection materielle, des algorithmes de filtrage, des schemas de pipeline de donnees et des modeles de couts de deploiement bases sur des deploiements en production dans des hopitaux, entrepots et usines.

1. Vue d’Ensemble de l’Architecture Systeme

Un systeme de suivi d’actifs BLE en production a quatre couches, chacune avec des exigences distinctes de latence, debit et fiabilite :

Couche Composants Latence Volume Impact Panne
T1: Couche Tags BLE tags (centaines a milliers) N/A (broadcast seul) ~30 octets/tag/event Actif individuel perdu
T2: Couche Passerelle Scanners BLE (5-50) 100-500 ms cycle ~50 KB/s crete par GW Zone perdue (10-50 tags)
T3: Couche Edge Serveur local ou appliance 1-5 s traitement ~200 KB/s agrege Suivi retarde, non perdu
T4: Couche Cloud Backend, BD, dashboard 1-10 s bout-en-bout ~500 KB/s soutenu Lacune donnees historiques

L’erreur d’architecture la plus courante est de traiter la passerelle comme un simple relais qui transmet les paquets BLE bruts au cloud. Avec 500 tags a intervalles de 1 seconde et 10 passerelles, ce sont 5.000 paquets par seconde qui frappent l’endpoint d’ingestion cloud, chacun contenant des lectures RSSI dupliquees de zones de couverture chevauchantes. Le filtrage edge n’est pas une optimisation ; c’est une exigence.

2. Selection Materielle de Passerelle

Plateforme Puce BLE CPU RAM Puissance Cout BOM Pour
Basee ESP32 ESP32 (dual-mode) 240 MHz Xtensa x2 520 KB SRAM 2,5W (WiFi+BLE) $3-5 Petits sites, WiFi
Raspberry Pi + USB nRF52840 dongle 1,4 GHz ARM A72 x4 1-4 GB 5-7W $45-60 R&D, prototypage
Passerelle dediee nRF52832/52840 + ESP32 ESP32 240MHz + nRF52 520KB + 256KB 2-3W $15-25 Deploiements production
Passerelle industrielle (Linux) CC2640R2 + WiFi/LTE ARM Cortex-A7 1GHz 512 MB 5-15W $200-400 Environnements durs, cellulaire

2.1 ESP32 comme Passerelle : Capacites et Limites

L’ESP32 est la plateforme passerelle la plus courante pour les deploiements sensibles aux couts car il integre WiFi et BLE. Cependant, le controleur BLE partage la radio 2,4 GHz entre WiFi et BLE, ce qui signifie qu’il ne peut pas scanner BLE pendant qu’il transmet WiFi :

Activite WiFi Trou de Scan BLE Perte (1s) Perte (500ms)
Inactif 0 ms 0% 0%
MQTT publish (toutes 5s) ~15 ms/trou 0,3% 0,6%
WiFi streaming (continu) ~50 ms/trou 1,0% 2,0%
OTA update ~200 ms/trou 5-8% 10-15%

2.2 Architecture de Passerelle Dediee

Les passerelles de production couplent typiquement un nRF52 (scanner BLE dedie) avec un ESP32 (WiFi/CPU). Le nRF52 execute un scan actif continu et transmet les paquets via UART/SPI a l’ESP32, qui gere le filtrage, la mise en tampon et la communication cloud. Ce design double puce elimine totalement la contention radio.

# Cote nRF52 : scanner BLE continu
def ble_scan_callback(adv_report):
    packet = {
        "mac": adv_report.peer_addr,
        "rssi": adv_report.rssi,
        "data": adv_report.data,
        "ts": get_timestamp_us(),
    }
    uart_send(json.dumps(packet))

# Cote ESP32 : recevoir, filtrer, upload par lot
rx_buffer = []
def uart_rx_callback(data):
    pkt = json.loads(data)
    if should_forward(pkt):
        rx_buffer.append(pkt)
    if len(rx_buffer) >= BATCH_SIZE or time_since_upload > INTERVAL:
        upload_batch(rx_buffer)
        rx_buffer.clear()

2.3 Placement des Passerelles et Couverture

Niveau Precision GW/100m2 Espacement Cout/m2 Cas d’Usage
Presence (piece) 0,5-1,0 10-15 m $0,15-0,30 Presence par zone
Position grossiere (3-5 m) 2-4 5-8 m $0,60-1,20 Suivi d’allee
Position fine (1-2 m) 6-10 3-5 m $1,80-3,00 Suivi d’instruments
Sub-metre (0,5 m) 15-25 2-3 m $4,50-7,50 Audit haute valeur

3. Strategie de Scan BLE

3.1 Scan Actif vs. Passif

Parametre Scan Passif Scan Actif
Envoie SCAN_REQ Non Oui
Recoit SCAN_RSP Non Oui (jusqu’a 31 octets extra)
Consommation Plus basse (Rx seul) Plus haute (Tx + Rx)
Donnees disponibles 31 octets 62 octets

3.2 Fenetre et Intervalle de Scan

Intervalle Fenetre Duty Cycle Capture (1s) Capture (500ms)
Continu Continu 100% ~99,5% ~99,0%
1000 ms 1000 ms 100% ~99,5% ~99,0%
1000 ms 500 ms 50% ~50-65% ~50-65%
5000 ms 1000 ms 20% ~20-30% ~20-30%

3.3 Filtrage des Doublons au Niveau Radio

Mode Doublons Paquets/s (500 tags, 1s, 10GW) CPU GW
Sans filtrage Tous ~15.000 Eleve
Dedup controleur 1/tag/cycle ~500 Bas
Dedup application 1/tag/fenetre ~500 Bas-Moyen

4. Filtrage Edge

4.1 Deduplication Multi-Passerelle

DEDUP_WINDOW_MS = 2000

def deduplicate(raw_reports):
    by_tag = group_by_mac(raw_reports)
    result = []
    for mac, reports in by_tag.items():
        if len(reports) == 1:
            result.append(reports[0])
            continue
        best = max(reports, key=lambda r: score_report(r))
        result.append(best)
    return result

def score_report(r):
    rssi_score = (r.rssi + 100) / 70
    age_s = (now() - r.ts) / 1000
    fresh_score = max(0, 1 - age_s / 5)
    gw_reliability = gateway_stats[r.gw_id].uptime_pct
    return rssi_score * 0.6 + fresh_score * 0.2 + gw_reliability * 0.2

4.2 Lissage RSSI et Rejet des Valeurs Aberrantes

Filtre Fenetre Latence Reduction Variance Complexite
Brut (sans filtre) 1 0 s 0% Aucune
Moyenne mobile 5 2-5 s ~55% Bas
Lissage exponentiel Infini 1-3 s ~50% Bas
Median 3-7 1-3 s ~65% Moyen
Kalman Adaptatif 0,5-2 s ~70% Eleve

4.3 Transmission Basee sur Evenements

Strategie Paq/Tag/Heure BW Cloud (500 tags) Cas d’Usage
Chaque scan (1s) 3.600 ~14 MB/h RTLS sous-seconde
Toutes 5s (lot) 720 ~2,8 MB/h Suivi standard
Changement zone seul ~5-20 ~40 KB/h Presence par piece
Seuil + heartbeat ~2-10 ~20 KB/h Alertes temperature

5. Conception de Pipeline de Donnees

5.1 Comparaison des Protocoles de Transport

Protocole Overhead Fiabilite Latence Puissance GW Pour
HTTP POST (JSON) ~400 octets TCP garantit 100-500 ms Eleve Petits deploiements
MQTT (QoS 1) ~20 octets TCP + ACK 50-200 ms Bas Deploiements production
UDP (custom) ~8 octets Aucune 10-50 ms Minimal RTLS temps reel, LAN
LoRaWAN ~13 octets Confirme 1-10 s N/A Sites distants sans WiFi

5.2 Structure des Topics MQTT

# Hierarchie de topics MQTT
# Format : site/zone/gateway/tag/event

site-001/zone-A/gw-01/+/scan
site-001/zone-A/+/tag-005/scan
site-001/+/+/tag-005/zone_change
site-001/+/+/+/battery_low
site-001/+/+/+/temperature_alert

# Payload (JSON, ~80 octets)
{
    "mac": "AA:BB:CC:DD:EE:01",
    "rssi": -67,
    "gw": "gw-01",
    "ts": 1722422400000,
    "bat": 85,
    "temp": 23.5,
    "seq": 4823
}

5.3 Schema de Donnees et Stockage

Store Technologie Donnees Retention Requete
Time-series (hot) InfluxDB / TimescaleDB Evenements bruts 7-30 jours Plage par tag + temps
Time-series (cold) S3 / Parquet Evenements agreges 1-5 ans Analytics batch
Relationnel PostgreSQL / MySQL Metadonnees, zones Permanent CRUD, jointures
Cache Redis Derniere position TTL 5 min Lookup sub-ms

5.4 Dimensionnement du Stockage

# 500 tags, intervalle 5s
tags = 500
events_per_hour = 500 * (3600 / 5)  # = 360.000
events_per_day = 360.000 * 24  # = 8.640.000
bytes_per_day = 8.640.000 * 80  # = 691 MB/jour
bytes_per_year = 691 * 365  # = ~252 GB (brut)
compressed_per_year = 252 / 5  # = ~50 GB (Parquet 5:1)
total_storage_year = 50 * 1.4  # = ~70 GB (avec overhead BD)

6. Estimation de Position a l’Edge

Algorithme GW Min Precision CPU Edge Calibration Pour
Proximite (RSSI max) 1 Piece (5-10m) Minimal Aucune Presence simple
Centroide pondere 3+ 3-5 m Bas Positions GW Zones ouvertes
Trilateration 3+ 2-4 m Moyen Exposant path-loss par zone Entrepots, couloirs
Fingerprinting (kNN) 4+ 1-3 m Moyen-Eleve Survey RF complet Interieurs complexes
BLE AoA 1 (antenne array) 0,5-1 m Eleve Calibration phase antenne Actifs haute valeur

6.1 Algorithme du Centroide Pondere

def estimate_position(reports, gateway_positions):
    total_weight = 0
    weighted_x = 0
    weighted_y = 0
    for r in reports:
        gw_id = r["gw_id"]
        if gw_id not in gateway_positions:
            continue
        weight = 10 ** (r["rssi"] / 10)
        gx, gy = gateway_positions[gw_id]
        weighted_x += weight * gx
        weighted_y += weight * gy
        total_weight += weight
    if total_weight == 0:
        return None
    return (weighted_x / total_weight, weighted_y / total_weight)

7. Fiabilite Systeme et Failover

7.1 Monitoring de Sante des Passerelles

Metric Normal Alerte Intervalle
Paquets/min 50-500 < 10 ou > 2000 60 s
Temp CPU 40-65 C > 75 C 300 s
WiFi RSSI -30 a -65 dBm < -75 dBm 60 s
Uptime > 99,5% < 99% Quotidien
Dernier heartbeat < 30 s > 120 s 30 s

7.2 Tampon en Cas de Perte de Connexion Edge-Cloud

Max Indisponibilite Tampon (500 tags, 5s) Support
15 min ~4,3 MB RAM
1 heure ~17 MB RAM/SD
4 heures ~69 MB SD/eMMC
24 heures ~415 MB SSD/eMMC

8. Modele de Cout de Deploiement

Systeme complet pour installation de 10.000 m2 avec 500 actifs :

Composant Qte Cout Unitaire Sous-total %
BLE tags (CR2032, 3 ans) 500 $8 $4.000 18%
Passerelles dediees 20 $120 $2.400 11%
Serveur edge 1 $800 $800 4%
Reseau + cablage 1 $1.500 $1.500 7%
Cloud (annee 1) 1 $3.600 $3.600 16%
Licences logiciel (annee 1) 1 $5.000 $5.000 23%
Installation + comissioning 1 $3.000 $3.000 14%
Pieces de rechange (10%) $640 3%
Survey RF + calibration 1 $1.200 $1.200 5%
Total Annee 1 $22.140 100%

Cout par actif : $22.140 / 500 = $44,28 (Annee 1), $8.640 / 500 = $17,28/an (recurrent). Plus economique que RFID ($60-120/actif) et Wi-Fi RTLS ($80-150/actif).

9. Benchmarks de Production

Metric Hopital (200 tags, 8GW) Entrepot (500 tags, 20GW) Usine (1000 tags, 15GW)
Taux de capture scan 98,2% 96,5% 94,1%
Precision (mediane) 3,2 m 4,8 m 5,5 m
Latence E2E (p95) 2,8 s 4,1 s 5,3 s
Uptime GW 99,7% 99,2% 98,8%
Donnees cloud/mois 4,2 GB 18,7 GB 24,3 GB
Faux changements zone 0,8% 2,1% 3,5%
Duree vie batterie (mediane) 31 mois 28 mois 26 mois

10. Considerations de Mise a l’Echelle

Echelle Tags GW Edge Cloud Defi
Petit 1-100 1-5 GW unique VPS unique Cout-efficacite
Moyen 100-1.000 5-30 Serveur edge VPS+Redis+TSDB Trous de couverture
Grand 1.000-5.000 30-100 Multi-edge Cluster LB Coord. edge-edge
Enterprise 5.000-50.000 100-500 Clusters regionaux K8s+TSDB distribue Aggregation multi-site

11. Erreurs Courantes d’Architecture

Erreur Symptome Cause Solution
Cloud traite tout Haute latence, cout eleve Pas de filtrage edge Dedup + lissage a l’edge
1 GW par zone Trous de couverture GW minimise 30-50% de chevauchement
HTTP pour tout Pics CPU, perte TCP handshake MQTT persistant
Pas de tampon offline Lacunes de donnees Fire-and-forget Tampon SQLite + replay
RSSI brut pour position Sauts de 5-10 m Pas de lissage Exponentiel alpha=0,3
Pas de timer de sejour Faux changements zone Flicker de couverture 30s sejour minimum
GW surprovisionne Donnees redondantes Plus = mieux 30-50% de chevauchement
Pas de gestion des tags Tags fantomes Tags morts non retires Auto-archivage 24h silencieux

13. Resume

Un systeme de suivi d’actifs BLE en production reussit ou echoue par son infrastructure, pas par ses tags. Le BLE tag est le composant le moins cher et le plus simple de la pile. Le reseau de passerelles, le pipeline de filtrage edge, le transport de donnees et le backend cloud determinent si le systeme livre une precision de 3 metres a 2 secondes de latence ou une precision de 10 metres a 30 secondes de latence. Les principes d’architecture sont clairs : filtrer tot et agressivement a l’edge, utiliser MQTT pour le transport, mettre en tampon pour le fonctionnement hors ligne et calibrer l’estimation de position par zone.