MQTT est devenu dans le secteur du pétrole et du gaz un moyen standard de surveiller les têtes de puits, les pipelines, les stations de compression et les parcs de stockage situés loin de toute fibre. Son modèle de report by exception, ses petits paquets et sa tolérance aux liaisons peu fiables correspondent aux réalités des liaisons cellulaires et satellite. Dans ce guide, vous apprendrez à concevoir une surveillance à distance avec MQTT, quels réglages de keep alive, de session et de QoS fonctionnent sur des liaisons coûteuses, et comment construire un publieur edge qui limite la bande passante sans perdre d'événements importants.
Pourquoi les actifs pétroliers et gaziers isolés se prêtent à MQTT
Les actifs amont et midstream partagent un ensemble de contraintes qui rendent l'interrogation classique pénible :
- Une bande passante chère ou limitée. Les forfaits satellite et certains forfaits cellulaires sont facturés à l'octet ou plafonnés. Interroger des valeurs inchangées toutes les quelques secondes coûte de l'argent pour rien.
- Une latence élevée. Les allers-retours par satellite géostationnaire sont longs : un maître qui interroge des centaines de sites séquentiellement finit avec des cycles de scrutation très lents.
- Une connectivité intermittente. La météo, l'alimentation et la couverture provoquent des coupures auxquelles le système de télémétrie doit survivre sans perdre d'alarmes.
- Des budgets énergétiques serrés. Les RTU et passerelles alimentées par panneau solaire veulent que la radio reste inactive le plus possible.
- Une exposition en matière de sécurité. Les sites isolés sont physiquement accessibles et se connectent via des réseaux publics.
MQTT répond directement à ces contraintes. Les équipements de terrain ouvrent une seule connexion TLS sortante et la maintiennent, ne publient que les changements significatifs et laissent le broker distribuer les données au SCADA, aux historians, aux outils d'analyse ou au jumeau numérique d'un site. Le guide MQTT dans les systèmes SCADA explique plus en détail ce passage de l'interrogation à la publication.
Architecture de référence
Une architecture MQTT typique dans le pétrole et le gaz comporte quatre couches :
- Instruments et contrôleurs de terrain. Calculateurs de débit, transmetteurs de pression et de température, radars de niveau de cuve, contrôleurs de pompes, systèmes d'arrêt d'urgence (ESD), qui parlent généralement Modbus ou un protocole propriétaire en local.
- Passerelle edge ou RTU. Elle lit les équipements locaux, applique des bandes mortes, horodate les valeurs, met en tampon pendant les coupures et publie en MQTT. Souvent en Sparkplug B pour la compatibilité SCADA.
- Liaison de collecte (backhaul). Cellulaire (LTE, LTE-M), radio sous licence ou libre, ou satellite (géostationnaire ou en orbite basse).
- Broker et consommateurs. Un broker central, avec comme abonnés les hôtes SCADA, les historians, la comptabilité de production et les systèmes de détection de fuites.
Gardez les fonctions de sécurité en local. L'arrêt d'urgence et la protection contre les surpressions ne doivent jamais dépendre de la liaison ou du broker ; MQTT transporte les données de surveillance et, lorsque c'est approuvé, uniquement des commandes de supervision.
Régler MQTT pour les liaisons cellulaires et satellite
Les réglages par défaut de la plupart des bibliothèques MQTT supposent un réseau local. Sur des liaisons distantes, quelques paramètres font la différence entre un système fiable et un système bavard et coûteux.
| Paramètre | Valeur par défaut en LAN | Recommandation pour les liaisons distantes | Pourquoi |
|---|---|---|---|
| Keep alive | 60 s | 60 à 300 s, mais en dessous du délai d'inactivité NAT de l'opérateur | Chaque PINGREQ coûte des octets ; trop long, et le NAT coupe silencieusement la session TCP |
| Session | Clean session | Session persistante (MQTT 5 : clean start à false plus session expiry) | Les abonnements et les messages QoS 1 en file survivent aux courtes coupures |
| QoS de la télémétrie | 0 ou 1 | 1 pour les événements et alarmes, 0 pour les valeurs à haute fréquence remplacées par l'échantillon suivant | Équilibrer garanties de livraison et surcoût des acquittements |
| Expiration des messages (MQTT 5) | Aucune | À définir sur les commandes et les données à courte durée de vie | Empêche une consigne périmée de s'exécuter après une longue coupure |
| Format du payload | JSON verbeux | JSON compact à clés courtes, ou Protobuf Sparkplug B | Les octets comptent sur les liaisons facturées au volume |
| Stratégie de publication | Intervalle fixe | Report by exception plus un heartbeat lent | La plupart des valeurs changent rarement |
| Délai de reconnexion | Immédiat | Exponentiel avec gigue (jitter) | Évite les tempêtes de reconnexions après une panne générale du réseau |
Keep alive et délais d'expiration NAT
Les opérateurs cellulaires placent les équipements derrière un NAT de niveau opérateur (CGNAT), qui supprime les flux TCP inactifs au-delà d'un délai qu'ils fixent eux-mêmes. Si votre keep alive est plus long, la connexion meurt silencieusement et l'équipement ne s'en aperçoit qu'à l'échec de sa publication suivante. Mesurez-le : commencez à 120 secondes, surveillez les reconnexions inexpliquées dans le journal de connexions du broker et raccourcissez jusqu'à ce qu'elles cessent. Sur les liaisons satellite, tenez aussi compte des longs allers-retours dans le choix du délai d'attente des pings côté client.
Report by exception pour les données de tête de puits
Une pression en tubing qui dérive de 0,1 % n'a pas besoin de traverser un satellite. Définissez des bandes mortes par tag en fonction de la précision de l'instrument et de la pertinence opérationnelle, publiez les états numériques et les alarmes à chaque changement, et envoyez un rafraîchissement complet toutes les 15 à 60 minutes comme preuve de vie. Le guide du report by exception traite du choix des bandes mortes, et store-and-forward pour MQTT explique comment mettre en tampon et rejouer les données à travers les coupures.
Exemple : un publieur edge économe en bande passante
Ce publieur Python utilise MQTT 5 avec une session persistante, des clés JSON courtes, des bandes mortes par tag, un heartbeat, l'expiration des messages sur les données de faible valeur et un délai de reconnexion exponentiel. Remplacez read_instruments() par vos lectures Modbus ou de calculateur de débit.
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.packettypes import PacketTypes
from paho.mqtt.properties import Properties
# Broker de test public pour le laboratoire : lisible par tous, n'utilisez que des données simulées.
BROKER, PORT, USE_TLS = "broker.connectmq.com", 1883, False
USERNAME, PASSWORD = None, None # production : "YOUR_USERNAME", "YOUR_PASSWORD"
CLIENT_ID = f"wellpad-{uuid.uuid4().hex[:8]}" # production : "YOUR_CLIENT_ID"
BASE = f"connectmq/demo/{uuid.uuid4().hex[:6]}/basin1/pad12/well3"
KEEPALIVE = 120
HEARTBEAT = 900 # rafraîchissement complet toutes les 15 minutes
DEADBANDS = {"tp": 2.0, "cp": 2.0, "ft": 0.5, "lv": 0.02} # psi, psi, degF, m
def read_instruments():
"""Valeurs simulées ; à remplacer par de vraies lectures Modbus ou de calculateur de débit."""
return {
"tp": round(850 + random.uniform(-3, 3), 1), # pression en tubing, psi
"cp": round(420 + random.uniform(-3, 3), 1), # pression en casing, psi
"ft": round(96 + random.uniform(-1, 1), 1), # température de la flowline, degF
"lv": round(2.41 + random.uniform(-0.03, 0.03), 3), # niveau de cuve, m
"esd": False, # ESD déclenché
}
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code, "session present:", flags.session_present)
client.publish(f"{BASE}/st", "online", qos=1, retain=True)
def on_disconnect(client, userdata, flags, reason_code, properties):
print("Disconnected:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID,
protocol=mqtt.MQTTv5)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if USE_TLS:
client.tls_set()
client.will_set(f"{BASE}/st", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=5, max_delay=300) # délai exponentiel
client.on_connect = on_connect
client.on_disconnect = on_disconnect
connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 1800 # conserver la session 30 minutes
client.connect(BROKER, PORT, keepalive=KEEPALIVE, clean_start=False,
properties=connect_props)
client.loop_start()
expiring = Properties(PacketTypes.PUBLISH)
expiring.MessageExpiryInterval = 3600 # les valeurs analogiques de plus d'1 h sont inutiles
last, last_full = {}, 0.0
print("Publishing under", BASE)
while True:
values = read_instruments()
now = time.time()
full = now - last_full >= HEARTBEAT
changed = {}
for key, value in values.items():
if isinstance(value, bool):
if full or value != last.get(key):
# alarmes et états : QoS 1, topic dédié, sans expiration
client.publish(f"{BASE}/alm/{key}", json.dumps(value), qos=1, retain=True)
last[key] = value
elif full or key not in last or abs(value - last[key]) >= DEADBANDS[key]:
changed[key] = value
last[key] = value
if changed:
changed["t"] = int(now) # secondes epoch : court et sans ambiguïté
client.publish(f"{BASE}/v", json.dumps(changed, separators=(",", ":")),
qos=1, properties=expiring)
if full:
last_full = now
time.sleep(10)
Un message de valeurs modifiées ressemble à {"tp":853.4,"t":1792139421}, soit quelques dizaines d'octets au lieu d'un instantané complet à chaque scrutation. Observez-le depuis votre bureau :
mosquitto_sub -h broker.connectmq.com -p 1883 -i wellpad-watch-01 \
-t 'connectmq/demo/+/basin1/#' -v
Le serveur MQTT public gratuit, réservé aux tests et aux prototypes, conserve les sessions jusqu'à 30 minutes, ce qui correspond à l'expiration de session ci-dessus ; c'est sur les brokers de production de votre propre plan que vous l'ajusterez à votre profil réel de coupures.
Sécurité des sites isolés
Les sites isolés sont exposés d'une manière que les équipements d'atelier ne connaissent pas. Appliquez au minimum ces mesures :
- TLS sur le port 8883 pour toute connexion via un réseau public, avec validation des certificats activée.
- Un nom d'utilisateur, un mot de passe et un client ID uniques par site, pour qu'une passerelle volée puisse être révoquée isolément.
- Une connectivité uniquement sortante ; aucun port entrant sur le modem cellulaire ou le terminal satellite.
- Lecture seule par défaut. Les commandes à distance, comme les changements de duse, nécessitent des circuits d'approbation, des verrouillages et l'expiration des messages.
- Des passerelles durcies : services inutiles désactivés, démarrage sécurisé quand il est disponible et protection physique contre l'effraction.
- Des alertes sur les déconnexions inattendues, qui peuvent signaler une tentative d'effraction autant qu'un problème de liaison.
Exploiter le broker
Le broker central est le composant partagé le plus important, et il doit être joignable depuis chaque site. ConnectMQ propose un broker MQTT managé avec MQTT 3.1.1 et 5.0, TLS, expiration des sessions et des messages, et identifiants par client. Son portail comprend un explorateur de topics en direct, une vue des équipements ISA-95 qui regroupe sites et actifs, et des règles d'alerte à seuil, par exemple sur un niveau de cuve ou une pression en casing, avec un journal des alertes à consulter. Les données des passerelles edge utilisant Sparkplug B peuvent être décodées et republiées dans des topics ISA-95 lisibles pour les consommateurs qui ne parlent pas Sparkplug. Pour les parcs plus importants, les plans payants et dédiés augmentent le nombre de connexions et la taille des messages, et le BYOC place le broker MQTT managé dans votre propre compte cloud.
Pour en savoir plus sur le choix des liaisons et le comportement des modems, consultez MQTT sur réseau cellulaire, et pour l'architecture d'ensemble, le guide de l'IoT industriel avec MQTT.
Surveillez vos actifs distants avec ConnectMQ
Commencez par une plateforme de puits ou une station de compression. Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire, connectez une passerelle edge en TLS et définissez votre première alerte à seuil sur une pression ou un niveau. Une fois le pilote validé, passez à l'échelle sur le même broker MQTT cloud ConnectMQ.
Questions fréquentes
MQTT fonctionne-t-il sur des liaisons satellite ?
Oui. Les connexions persistantes, les en-têtes compacts et la publication en report by exception de MQTT conviennent aux liaisons satellite à forte latence. Réglez le keep alive, utilisez des sessions persistantes et gardez des payloads compacts.
Quel keep alive utiliser en cellulaire ?
Commencez autour de 120 secondes et restez en dessous du délai d'inactivité NAT de l'opérateur. Si vous constatez des reconnexions inexpliquées, raccourcissez-le.
Sparkplug B ou JSON : lequel est le meilleur pour la télémétrie pétrolière et gazière ?
Sparkplug B est plus compact et s'intègre bien aux hôtes SCADA. Le JSON à clés courtes est plus facile à inspecter et convient parfaitement lorsque les payloads sont petits et les changements peu fréquents.
Faut-il envoyer les commandes d'arrêt via MQTT ?
Non. Les fonctions de sécurité doivent rester locales et indépendantes du réseau. MQTT convient à la surveillance et, avec des garde-fous appropriés, aux commandes de supervision.



