L'intégration MQTT d'une borne de recharge permet à votre wallbox de participer au reste du système énergétique de la maison connectée : recharger quand le soleil brille, faire une pause quand le four et la pompe à chaleur tournent, et afficher son état sur le même tableau de bord que tout le reste. Ce guide explique en quoi OCPP et MQTT diffèrent, les trois façons concrètes de faire passer une borne sur MQTT, une conception de topics propre et un régulateur de surplus solaire fonctionnel en Python. À la fin, vous saurez quelle voie convient à votre borne et comment bâtir dessus en toute sécurité.
OCPP et MQTT résolvent des problèmes différents
On demande souvent si une borne doit utiliser OCPP ou MQTT. En pratique, ils servent des relations différentes, et une bonne installation domestique utilise souvent les deux.
OCPP (Open Charge Point Protocol) est le langage standard entre une borne et un système de gestion de stations de recharge (CSMS), le back-office qui gère l'autorisation, les sessions et la facturation. OCPP 1.6J et 2.0.1 font transiter des messages JSON sur une WebSocket que la borne ouvre vers le CSMS. Les messages incluent BootNotification, StatusNotification, MeterValues, le début et la fin de transaction, ainsi que SetChargingProfile pour la recharge intelligente. Chaque borne se connecte à un seul CSMS à la fois.
MQTT est un protocole publish/subscribe généraliste. Une borne ou une passerelle publie son état vers un broker, et un nombre quelconque de consommateurs (tableau de bord, Home Assistant, gestionnaire d'énergie, application mobile) s'y abonnent sans que la borne les connaisse ; Jeedom et Domoticz savent aussi communiquer en MQTT. Si ce modèle est nouveau pour vous, l'explication de ce que fait un broker MQTT couvre les bases.
| Aspect | OCPP | MQTT |
|---|---|---|
| Objectif | Borne vers back-office : sessions, authentification, facturation, recharge intelligente | N'importe quel appareil vers un nombre quelconque de consommateurs |
| Transport | WebSocket, la borne se connecte à un seul CSMS | TCP ou WebSocket vers un broker, nombreux abonnés |
| Schéma des messages | Strictement défini par version d'OCPP | Vous concevez les topics et les payloads |
| Utilisateur type | Opérateurs de recharge, flottes, recharge en entreprise | Domotique, gestion de l'énergie, tableaux de bord |
| Contrôle | Démarrage/arrêt à distance, profils de recharge | Ce que l'appareil ou la passerelle expose |
| Multi-consommateurs | Non, un CSMS par connexion | Oui, nativement |
Si vous exploitez des bornes publiques ou en entreprise, OCPP vers un CSMS constitue le bon socle. Si vous voulez qu'une borne domestique coopère avec des panneaux solaires, des batteries et les charges du foyer, MQTT est la couche d'intégration pratique, parfois alimentée par OCPP en coulisses.
Trois façons de faire passer une borne de recharge sur MQTT
1. MQTT natif dans la borne. Certaines bornes, en particulier les modèles open hardware ou destinés aux passionnés, publient leur état et acceptent des commandes directement en MQTT. Vous saisissez l'hôte du broker, le port et les identifiants dans l'interface web de la borne. C'est la voie la plus simple lorsqu'elle existe, mais les noms de topics et les payloads varient selon le fabricant.
2. Un serveur OCPP local qui fait le pont vers MQTT. Beaucoup de wallbox commerciales ne parlent qu'OCPP (en plus du cloud du fabricant). Pointez l'URL OCPP de la borne vers un serveur OCPP local, par exemple l'intégration OCPP de Home Assistant ou un CSMS open source, et laissez ce serveur republier l'état et les relevés de compteur en MQTT. Vous conservez la sémantique standard d'OCPP et gagnez MQTT pour tout le reste. La contrepartie : les fonctions cloud du fabricant peuvent cesser de fonctionner tant que la borne parle à votre serveur.
3. Un gestionnaire d'énergie entre les deux. Les gestionnaires d'énergie open source comme evcc dialoguent avec de nombreuses bornes via leurs protocoles natifs et publient leur propre état en MQTT, notamment la puissance réseau, la puissance PV et la puissance de recharge par point de charge, tout en acceptant des changements de mode via des topics MQTT. C'est souvent la voie la plus rapide vers une recharge solaire intelligente, car la logique de régulation est déjà construite et testée.
Quelle que soit la voie choisie, visez le même résultat sur le broker : une arborescence de topics stable qui ne change pas si vous remplacez la borne.
Concevoir l'arborescence de topics MQTT de la borne
Séparez l'état des commandes, retenez l'état et ne retenez jamais les commandes :
home/ev/charger1/state retained {"status":"charging","power_w":7210,"current_a":10.4,"phases":3,"session_kwh":12.8}
home/ev/charger1/status retained online / offline (Last Will)
home/ev/charger1/set/current_a command 6..16
home/ev/charger1/set/enabled command true / false
home/energy/grid/telemetry retained {"net_w": -2350, ...}
Utilisez des valeurs d'état de type OCPP (available, preparing, charging, suspended_ev, suspended_evse, finishing, faulted) même lorsque la source n'est pas OCPP. Elles sont bien connues et distinguent « la voiture est pleine » (suspended_ev) de « la borne est en pause » (suspended_evse), ce qui compte pour les automatisations.
Retenir une commande comme set/current_a est une erreur classique : après une coupure de courant, la borne ou la passerelle se reconnecte et rejoue une ancienne valeur. Les commandes ne doivent pas être retenues ; la passerelle republie la valeur effective sur le topic d'état retenu.
Un régulateur de surplus solaire en Python
Le régulateur ci-dessous s'abonne au net_w du compteur réseau (une valeur négative signifie une injection, tel que publié dans le tutoriel de suivi énergétique de la maison) et à l'état de la borne, puis publie un courant de charge qui suit le surplus. Il fonctionne avec toute borne ou passerelle acceptant une consigne de courant sur un topic. Testez-le sur le serveur MQTT public gratuit avec des messages simulés avant de connecter quoi que ce soit de réel.
pip install "paho-mqtt>=2.0"
import json
import time
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/ev7k2" # utilisez votre propre préfixe aléatoire pendant les tests
GRID_TOPIC = f"{PREFIX}/energy/grid/telemetry"
STATE_TOPIC = f"{PREFIX}/ev/charger1/state"
SET_CURRENT = f"{PREFIX}/ev/charger1/set/current_a"
SET_ENABLED = f"{PREFIX}/ev/charger1/set/enabled"
VOLTAGE = 230
PHASES = 1 # mettez 3 pour une borne triphasée
MIN_A, MAX_A = 6, 16 # 6 A est le courant minimal de la signalisation IEC 61851
START_MARGIN_W = 300 # injection supplémentaire requise avant de démarrer
UPDATE_EVERY = 30 # secondes entre deux changements de consigne
STOP_AFTER = 300 # secondes sous le minimum avant la mise en pause
state = {"net_w": None, "charger_current_a": 0.0, "status": "unknown"}
current_set = 0
below_since = None
last_update = 0.0
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(GRID_TOPIC, qos=1)
client.subscribe(STATE_TOPIC, qos=1)
def on_message(client, userdata, msg):
data = json.loads(msg.payload)
if msg.topic == GRID_TOPIC:
state["net_w"] = data.get("net_w")
elif msg.topic == STATE_TOPIC:
state["charger_current_a"] = data.get("current_a", 0.0)
state["status"] = data.get("status", "unknown")
def control(client):
global current_set, below_since, last_update
if state["net_w"] is None or state["status"] in ("available", "faulted", "unknown"):
return
if time.time() - last_update < UPDATE_EVERY:
return
charger_w = state["charger_current_a"] * VOLTAGE * PHASES
surplus_w = charger_w - state["net_w"] # ce que l'on peut utiliser sans soutirer
if current_set == 0:
surplus_w -= START_MARGIN_W
target = int(surplus_w // (VOLTAGE * PHASES))
if target >= MIN_A:
below_since = None
target = min(target, MAX_A)
if current_set == 0:
client.publish(SET_ENABLED, "true", qos=1)
if target != current_set:
client.publish(SET_CURRENT, str(target), qos=1)
print(f"surplus {surplus_w:.0f} W -> {target} A")
current_set = target
elif current_set > 0:
below_since = below_since or time.time()
if time.time() - below_since > STOP_AFTER:
client.publish(SET_ENABLED, "false", qos=1)
print("Not enough surplus, pausing")
current_set = 0
elif current_set != MIN_A:
client.publish(SET_CURRENT, str(MIN_A), qos=1)
current_set = MIN_A
last_update = time.time()
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="ev-surplus-6619")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
while True:
control(client)
time.sleep(1)
Simulez un après-midi ensoleillé depuis un autre terminal et observez la réaction du régulateur :
mosquitto_pub -h broker.connectmq.com -p 1883 -i ev-sim-1 -t "connectmq/demo/ev7k2/ev/charger1/state" -m '{"status":"suspended_evse","current_a":0}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i ev-sim-2 -t "connectmq/demo/ev7k2/energy/grid/telemetry" -m '{"net_w":-2600}'
Avec 2 600 W d'injection sur une seule phase, le régulateur démarre à 10 A après déduction de la marge de démarrage.
Règles de conception pour piloter une borne en toute sécurité
Le matériel de recharge supporte de forts courants pendant des heures ; soyez donc prudent :
- Laissez la borne appliquer ses propres limites. Votre régulateur ne fait que demander une consigne ; le maximum configuré sur la borne et les protections de l'installation doivent rester l'autorité finale.
- Modifiez les consignes lentement. Des changements de courant fréquents et des cycles marche/arrêt répétés usent les contacteurs et posent problème à certains véhicules. Un intervalle de mise à jour de 30 secondes et un délai d'arrêt de 5 minutes sont de bons points de départ.
- Respectez le minimum de 6 A. En dessous, mettez la recharge en pause plutôt que de demander un courant invalide.
- Gérez la commutation de phases avec soin. Passer d'une à trois phases exige que la borne le prenne en charge et ne doit jamais se produire pendant que le courant circule.
- Prévoyez un repli sûr. Si le compteur réseau cesse de remonter des données, arrêtez les ajustements et revenez à un état fixe ou en pause. Utilisez le statut Last Will retenu du compteur pour le détecter.
- Ne pilotez jamais une borne via le serveur MQTT public gratuit. N'importe qui pourrait publier sur votre topic de commande. Ce serveur est réservé aux tests et à la simulation.
Passer à un broker privé
Une fois la simulation concluante, connectez la vraie borne ou la passerelle et le régulateur à un broker privé avec TLS et des identifiants par client. Un broker MQTT managé comme ConnectMQ maintient ce broker en ligne sans serveur à administrer, et comme votre borne, votre lecteur de compteur et votre régulateur n'établissent que des connexions sortantes, rien n'a besoin d'être exposé sur votre box. Dans le portail ConnectMQ, créez un broker, émettez des identifiants pour chaque client et connectez-vous sur le port 8883 :
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=60)
Intégrez ensuite les données de production issues du suivi d'onduleur solaire et celles du stockage issues du suivi de batterie domestique pour décider si la voiture ou la batterie reçoit le surplus en priorité. Le guide de l'automatisation IoT montre comment ces flux d'énergie s'intègrent dans une installation domestique plus large, et le guide du broker MQTT cloud vous aide à choisir où l'héberger.
Connectez votre borne à ConnectMQ
ConnectMQ offre à votre passerelle de borne, à votre gestionnaire d'énergie et à vos tableaux de bord un broker privé avec TLS, un accès WebSocket pour les applications web et un explorateur de topics en direct pour vérifier chaque changement d'état. Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire.
Questions fréquentes
Ma borne domestique doit-elle utiliser OCPP ou MQTT ?
Utilisez ce que la borne prend en charge nativement pour sa connexion principale, et MQTT comme couche d'intégration pour la domotique. Beaucoup d'installations font tourner OCPP vers un serveur local qui republie en MQTT.
Puis-je utiliser OCPP et le cloud du fabricant en même temps ?
Généralement non, car une borne se connecte à un seul backend OCPP. La pointer vers votre propre serveur remplace en général le backend du fabricant ; vérifiez donc quelles fonctions vous perdriez.
Quel est le courant de charge minimal ?
La signalisation par fil pilote IEC 61851 utilisée par les bornes AC impose un minimum de 6 A. En dessous, le régulateur doit mettre la recharge en pause au lieu de baisser encore le courant.
À quelle vitesse un régulateur de surplus doit-il réagir ?
Toutes les 30 à 60 secondes est une valeur par défaut raisonnable. Des réactions plus rapides ne font surtout que suivre les nuages de passage et provoquent des commutations inutiles.



