L'historique des graphiques Node-RED disparaît à chaque redémarrage de Node-RED, car les graphiques du Dashboard conservent leurs points en mémoire. Ce tutoriel présente deux méthodes pratiques pour conserver cet historique pour des données MQTT : un stockage de contexte sur fichier pour les petits volumes, et une table SQLite lorsque vous voulez des requêtes et une rétention plus longue. Dans les deux cas, vous rejouerez les données stockées dans un graphique Dashboard 2.0 au démarrage, pour que les opérateurs voient les dernières 24 heures plutôt qu'une grille vide.
Pourquoi les graphiques Node-RED perdent leur historique
Un nœud ui-chart de Dashboard 2.0 stocke les points reçus dans un magasin de données côté serveur, ce qui explique qu'un nouvel onglet de navigateur affiche quand même la courbe existante. Ce magasin réside dans la mémoire du processus Node-RED. Redémarrez Node-RED, redémarrez le Raspberry Pi sur lequel il tourne, ou mettez à jour un paquet puis redémarrez, et le graphique repart de zéro.
MQTT ne comble pas ce vide à lui seul. Un retained message ne conserve que la dernière valeur par topic : un abonné qui se reconnecte reçoit un point, pas une tendance. Un broker est un routeur de messages, pas une base de données. Pour comprendre exactement où se situe cette frontière, lisez ce que fait un broker MQTT. L'historique doit être stocké dans un endroit que vous maîtrisez, et Node-RED est un emplacement pratique pour cela.
Choisir une méthode de stockage pour l'historique des graphiques Node-RED
| Méthode | Adaptée à | Rétention | Installation supplémentaire | Compromis |
|---|---|---|---|---|
Contexte sur fichier (localfilesystem) |
Une à quelques séries, un point par minute | Quelques heures à quelques jours | Aucune | Tableau entier réécrit à chaque écriture ; pas de requêtes |
SQLite (node-red-node-sqlite) |
Nombreuses séries, filtrage par plage de temps | Semaines à mois | Un nœud de la palette | Nettoyage de la table à votre charge |
| Base de données de séries temporelles (InfluxDB) | Nombreux appareils, agrégation, Grafana | Mois à années | Serveur séparé | Davantage de composants |
La suite de cet article met en œuvre les deux premières. Pour la troisième, suivez le tutoriel Node-RED InfluxDB, qui utilise la même entrée MQTT et une base de données conçue pour cet usage.
Des données de test depuis un broker gratuit
Il vous faut un flux de mesures. Publiez une température toutes les quelques secondes sur broker.connectmq.com, le serveur MQTT public gratuit, avec un préfixe de topic unique. Remplacez a7f3k2 par votre propre chaîne aléatoire ; tout ce qui transite sur le serveur public est lisible par tout le monde, réservez-le donc aux tests.
# Publie une température aléatoire toutes les 5 secondes (Ctrl+C pour arrêter)
while true; do
T=$(awk -v r=$RANDOM 'BEGIN { printf "%.2f", 20 + (r % 800) / 100 }')
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-hist-a7f3k2 \
-t connectmq/demo/a7f3k2/room1/telemetry -m "{\"temperature\": $T}"
sleep 5
done
Dans Node-RED, ajoutez un nœud mqtt in sur connectmq/demo/a7f3k2/room1/telemetry, avec la sortie « a parsed JSON object », en utilisant un nœud de configuration de broker doté d'un client ID unique.
Méthode 1 : stockage de contexte sur fichier
Activer un magasin de contexte persistant
Par défaut, le contexte Node-RED réside en mémoire. Modifiez settings.js dans votre répertoire utilisateur Node-RED (généralement ~/.node-red/settings.js) et définissez un second magasin qui écrit sur disque :
// ~/.node-red/settings.js (dans module.exports = { ... })
contextStorage: {
default: { module: "memory" },
file: {
module: "localfilesystem",
config: { flushInterval: 30 } // secondes entre deux écritures sur disque
}
},
Redémarrez Node-RED. Garder la mémoire par défaut et nommer explicitement le magasin fichier signifie que seules les données que vous choisissez sont écrites sur disque, ce qui compte sur les cartes SD. Les valeurs sont écrites toutes les 30 secondes : une coupure de courant brutale peut faire perdre jusqu'à cette fenêtre, alors qu'un arrêt propre écrit tout. Le guide du contexte Node-RED détaille les portées et les magasins.
Enregistrer un point par minute
Stocker chaque mesure brute produit rapidement un gros tableau réécrit à chaque écriture. Faites plutôt la moyenne des mesures par minute. Reliez le nœud mqtt in à ce nœud function et reliez sa sortie au graphique :
// Nœud function "record history" - 1 sortie
const RETENTION_MS = 24 * 60 * 60 * 1000; // conserver 24 heures
const value = Number(msg.payload.temperature);
if (Number.isNaN(value)) {
return null;
}
const now = Date.now();
const minute = Math.floor(now / 60000);
let acc = context.get("acc") || { minute: minute, sum: 0, n: 0 };
if (acc.minute !== minute) {
if (acc.n > 0) {
let history = flow.get("tempHistory", "file") || [];
history.push({
x: acc.minute * 60000,
y: Math.round((acc.sum / acc.n) * 100) / 100
});
const cutoff = now - RETENTION_MS;
history = history.filter(p => p.x >= cutoff);
flow.set("tempHistory", history, "file");
}
acc = { minute: minute, sum: 0, n: 0 };
}
acc.sum += value;
acc.n += 1;
context.set("acc", acc);
// Point en direct pour le graphique
return { topic: "Temperature", payload: { x: now, y: value } };
À un point par minute, une journée d'historique représente 1 440 petits objets par série, ce qu'un fichier de contexte gère sans difficulté.
Configurer le graphique
Dans le nœud ui-chart, choisissez un graphique en courbe, laissez Series sur msg.topic, réglez X sur la clé x et Y sur la clé y, et limitez le graphique à 24 heures de points pour qu'il corresponde à votre rétention.
Rejouer l'historique au démarrage
Ajoutez un nœud inject réglé sur Inject once after 1 second, sans répétition, et reliez-le à ce nœud function, puis au même graphique :
// Nœud function "replay history" - 1 sortie
const history = flow.get("tempHistory", "file") || [];
node.status({ fill: "green", shape: "dot", text: history.length + " points" });
return [[
{ topic: "Temperature", payload: [] }, // vider d'abord le graphique
{ topic: "Temperature", payload: history } // puis envoyer le tableau stocké
]];
Envoyer un tableau vide efface le graphique, ce qui évite les courbes dupliquées après un redéploiement. Envoyer un tableau d'objets {x, y} les ajoute tous d'un coup. Redémarrez Node-RED : le graphique revient avec les moyennes de la dernière journée, puis continue avec les points en direct.
Méthode 2 : SQLite pour une rétention plus longue
Lorsque vous avez plusieurs séries, voulez une semaine ou plus, ou souhaitez filtrer par période, une base de données est plus propre. Installez node-red-node-sqlite depuis le gestionnaire de palette. Sur certaines plateformes, cela compile un module natif ; laissez-lui une minute.
Créer la table
Ajoutez un nœud inject (une seule injection au démarrage) avec msg.topic défini sur l'instruction ci-dessous, et reliez-le à un nœud sqlite utilisant le fichier de base /home/pi/.node-red/history.db (adaptez le chemin) et le mode de requête SQL Via msg.topic.
CREATE TABLE IF NOT EXISTS readings (
ts INTEGER NOT NULL,
series TEXT NOT NULL,
value REAL NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_readings ON readings (series, ts);
Si votre version du nœud n'exécute qu'une instruction par message, envoyez les deux instructions via deux injections séparées.
Insérer chaque mesure
Utilisez un second nœud sqlite en mode Prepared Statement avec ce SQL :
INSERT INTO readings (ts, series, value) VALUES ($ts, $series, $value)
Alimentez-le depuis un nœud function qui construit les paramètres :
// Nœud function "to sqlite params"
const value = Number(msg.payload.temperature);
if (Number.isNaN(value)) return null;
msg.params = { $ts: Date.now(), $series: "Temperature", $value: value };
return msg;
Interroger au démarrage et nettoyer chaque jour
Au démarrage, interrogez les dernières 24 heures et envoyez les lignes au graphique. Un nœud sqlite en mode Via msg.topic renvoie les lignes sous forme de tableau dans msg.payload :
// Nœud function "history query" - déclenché par un inject unique au démarrage
msg.topic = "SELECT ts AS x, value AS y FROM readings " +
"WHERE series = 'Temperature' AND ts > " + (Date.now() - 86400000) +
" ORDER BY ts";
return msg;
Faites passer le résultat par un nœud change qui définit msg.topic sur Temperature, puis vers le graphique. Ajoutez un inject quotidien qui exécute DELETE FROM readings WHERE ts < <cutoff> avec une limite calculée de la même façon, pour que le fichier ne grossisse pas indéfiniment.
Liste de contrôle avant de vous y fier
- Choisissez une durée de rétention et appliquez-la dans le code ou en SQL, pas en comptant sur la chance.
- Sous-échantillonnez avant de stocker si vous n'affichez que des moyennes.
- Vérifiez que la limite de points du graphique correspond à la rétention, sinon les anciens points disparaissent trop tôt.
- Videz le graphique avant de rejouer pour éviter les courbes dupliquées après un déploiement.
- Sauvegardez le répertoire de contexte ou le fichier de base de données avec le reste de votre projet Node-RED.
- Surveillez l'espace disque sur les cartes SD ; préférez SQLite ou une base externe pour les données haute fréquence.
D'où doivent venir les données en production
Un historique ne vaut que par le flux qui l'alimente. Si le broker tombe, des trous apparaissent dans le graphique, et sur un broker public partagé, n'importe qui peut lire vos topics de démonstration ou y publier. Pour de vraies installations, pointez le nœud mqtt in vers un broker privé avec identifiants et TLS. Avec ConnectMQ, le portail délivre un nom d'utilisateur, un mot de passe et un client ID pour chaque broker, et la modification du flow se limite au nœud de configuration : serveur, port 8883, TLS activé et identifiants.
Un broker MQTT managé permet aussi aux appareils de continuer à publier pendant que vous redémarrez ou mettez à jour Node-RED. Associez-le à une session MQTT persistante et à QoS 1 sur l'abonnement, et les courts redémarrages de Node-RED peuvent être couverts par la mise en file des messages de la session par le broker, dans la limite de l'expiration de session de votre offre. Pour les tableaux de bord eux-mêmes, le tutoriel Dashboard 2.0 couvre les jauges, les contrôles et la mise en page, et le tutoriel Node-RED MQTT couvre les bases du broker.
Gardez vos données Node-RED en mouvement avec ConnectMQ
Inscrivez-vous sur app.connectmq.com et commencez avec l'offre Serverless gratuite, sans carte bancaire. Créez un broker, collez les identifiants dans votre nœud de configuration Node-RED, et vos graphiques sont alimentés par un flux privé chiffré en TLS. L'explorateur de topics en direct de ConnectMQ vous aide à confirmer que les mesures arrivent avant de commencer à déboguer le stockage.
Questions fréquentes
Node-RED Dashboard 2.0 enregistre-t-il automatiquement les données des graphiques ?
Il conserve les données des graphiques en mémoire pour que les nouveaux onglets voient les points existants, mais rien n'est écrit sur disque. Après un redémarrage de Node-RED, le graphique est vide sauf si vous rejouez des données stockées.
Les retained messages MQTT peuvent-ils stocker l'historique d'un graphique ?
Non. Un retained message ne contient que la dernière valeur d'un topic. Il est utile pour afficher immédiatement l'état actuel, mais il faut un stockage de contexte ou une base de données pour une tendance.
Quelle quantité d'historique puis-je garder dans le contexte Node-RED ?
Le contexte sur fichier fonctionne bien pour quelques séries sous-échantillonnées à un point par minute sur une journée ou quelques jours. Pour des volumes plus importants, utilisez SQLite ou une base de séries temporelles comme InfluxDB.
Comment éviter les courbes dupliquées après un déploiement ?
Envoyez un tableau vide au graphique avant de rejouer les points stockés. Cela efface le graphique pour que l'historique ne soit dessiné qu'une fois.



