Bonjour tout le monde ,
J'ai une petite applet nodeJS qui tourne sur raspberry pi 0 avec un setInterval qui me sert a mesurer la température.
Or, ce setInterval() s'arrête systématiquement tout seul a bout d'un certain nombre d'utilisation.
ci joint, le lien vers un autre forum ou j'ai aussi posé mon problème : https://openclassrooms.com/forum/sujet/nodejs-arret-setinterval
le code :
const sondeTemperature = require('ds18b20-raspi'); // Pour utiliser une sonde ds18b20 étanche
const nodemailer = require('nodemailer'); // je me sert des mails pour recevoir les erreurs et les températures
const logs = require('fs'); // pour écrire un fichier de log
const bdd = require('mysql'); //bdd
//variables nécéssaires
const listeSonde = sondeTemperature.list(); // recense la liste des capteurs de température disponible (1 dans mon cas)
var boolTemperature = 0; // Me sert plus tard pour connaitre l'état de la sonde
const TempscooldownMail = 5; //sert pour empêcher le spam de mail, 1 mil toute les 5 minutes
var cooldownMail = 0; // un itérateur que je vais faire courrir pour les mails
var nbBoucle = 12; // nombre de cycle avant d'appeler MesurePeriodiqueHeure()
//en cas d'erreurs, les infos mails
const transporter = nodemailer.createTransport(
{
service: 'gmail',
auth:
{
user: '',
pass: ''
}
});
//tableau pour stocker des données const et var
var tabDonnee = new Array();
setTimeout( ()=> { // j'attend 1 seconde avant de recennser les sondes, histoire de laisser le temps a listeSonde d'être initialisé
if(listeSonde.length < 1) // si pas de sonde
{
boolTemperature = 1; // erreur sonde a 1
mailAlerte("sondeManquante"); // evoie d'une alerte mail
erreurLogs("sondeManquante"); // ecriture dans les logs
return;
}
else // si au moins une sonde
{
tabDonnee[1] = new Array();
tabDonnee[1][0] = listeSonde[0]; //Adresse de la sonde de température
tabDonnee[1][1] = sondeTemperature.readC(listeSonde[0]); //température actuel en celsius
tabDonnee[1][3] = "28.00" // température seuil haut (maximum ,dans l'aquarium)
tabDonnee[1][4] = "25.00" // température seuil bas (minimum ,dans l'aquarium)
}
},1000);
erreurLogs("applet démarré, variables initialisés."); // petit test
let timerMinute = setInterval(() => {VerifMinute();}, 300000); //Ceci permet de boucler toute les 5 minutes sur ma fonction qui mesure la température. -- 60000
function VerifMinute() // fonction principale du programme
{
erreurLogs("verifminute lancé"); // petit test #2
var heure = new Date(); // variable a créer a chaque itération pour quelle sois a jour
var temp = (heure.getHours()<10?'0':'') + heure.getHours()+":"+(heure.getMinutes()<10?'0':'') + heure.getMinutes(); // si le chiffre des heures est inférieur a 10 (donc de 0 à 9) il faut ajouter un 0 non significatif devant
//vérification de la température et des seuils
if(boolTemperature == 0 & cooldownMail == 0) // si caoteur de température est oK et pas de mails dans les 5 dernières minutes
{
tabDonnee[1][1] = sondeTemperature.readC(tabDonnee[1][0]); // je lis la température
if((tabDonnee[1][1] < tabDonnee[1][4]) | (tabDonnee[1][1] > tabDonnee[1][3])) // je compare ma lecture aux seuils a ne pas franchir
{
mailAlerte("seuilTemperature"); // si un seuil est franchis, j'alerte par mail
}
}
if(cooldownMail > 0) cooldownMail = cooldownMail -1; // si il y a eu un mail dans les 5 dernières minutes, je décrémente mon itérateur
if(nbBoucle > 11) // mon fameux cycle pour appeler ma deuxième fonction
{
nbBoucle = 0; // reset du cycle
MesurePeriodiqueHeure(); //permet de stocker la température actuel dans une BDD
}
else nbBoucle = nbBoucle +1; // je note mon nouveau cycle
heure = temp = null; // j'ai essayé de libérer les variables pour contenir la mémoire
}
function MesurePeriodiqueHeure()
{
var dateHeure = new Date(); // sert pour récupérer l'heure
var date = dateHeure.getFullYear()+"-"+(dateHeure.getMonth()+1)+"-"+dateHeure.getDate();
var heure = (dateHeure.getHours()<10?'0':'') + dateHeure.getHours()+":"+(dateHeure.getMinutes()<10?'0':'') + dateHeure.getMinutes()+":"+(dateHeure.getSeconds()<10?'0':'') + dateHeure.getSeconds();
if(boolTemperature == 0) // si mon capteur de température est ok
{
var mySqlClient = bdd.createConnection( // je me connecte a la BDD
{
host : "localhost",
user : "aquarium",
password : "",
database : "Aquarium"
});
var selectQuery = "INSERT INTO `historique_temperature`(`date`, `heure`, `num_sonde`, `temperature`) VALUES (\""+date+"\",\""+heure+"\",\""+tabDonnee[1][0]+"\",\""+tabDonnee[1][1]+"\")";
mySqlClient.query(selectQuery,function select(error, results, fields)
{
if (error) //si erreur avec la requete
{
mySqlClient.end();// je coupe la connexion
mailAlerte("erreurBDD"); //je mail
erreurLogs("erreur BDD : "+error); //je log
return;
}
date = heure = dateheure = null; //vidage de la mémoire
});
}
}
function mailAlerte(erreur) // pour alerter, pas d'explications car fonctionnel
{
if(cooldownMail <= 0)
{
switch(erreur)
{
case "sondeManquante" :
var mailOptions = {
from: '',
to: '',
cc: '',
subject: 'Aquarium - Attention requise',
text: 'Le système de l\'aquarium a détecté un problème.\n Aucune sonde de température détectée. La température ne peut pas être mesurée.\nLe problème ne peut être résolue par le système.\n L\'attention d\'un opérateur est requise. \n\n Bien à vous, Jean-Michel, BOT assistant.\n\n\n -- Robot, ne pas répondre à ce mail --'
};
break;
case "seuilTemperature" :
var mailOptions = {
from: '',
to: '',
cc: '',
subject: 'Aquarium - Attention requise',
text: 'Le système de l\'aquarium a détecté un problème.\n Un seuil de température a été franchi.\nTempérature actuelle : '+tabDonnee[1][1]+'°C, mesurée par la sonde : '+tabDonnee[1][0]+'\n seuil minimum : '+tabDonnee[1][4]+'°C\n seuil maximum : '+tabDonnee[1][3]+'°C\nSonde en cours de redémarrage. \n\n Bien à vous, Jean-Michel, BOT assistant.\n\n\n -- Robot, ne pas répondre à ce mail --'
};
break;
case "erreurBDD" :
var mailOptions = {
from: '',
to: '',
cc: '',
subject: 'Aquarium - Attention requise',
text: 'Le système de l\'aquarium a détecté un problème.\n La base de donnée a envoyé une erreur. Insertion des données impossibles. \n\n Bien à vous, Jean-Michel, BOT assistant.\n\n\n -- Robot, ne pas répondre à ce mail --'
};
break;
}
setTimeout(function()
{
transporter.sendMail(mailOptions, function(error, info){
if (error) {erreurLogs("erreur mail : "+error);return;}
else {
cooldownMail = TempscooldownMail;
}
});
},1000);
}
}
function erreurLogs(donnee) // logs
{
var { rss, heapTotal, heapUsed } = process.memoryUsage();
var contenu = donnee + ".\nTaille applet : "+ rss+"\nTaille objet total : "+heapTotal+"\nTaille objet réel : "+heapUsed+"\n";
var dateHeure = new Date();
var heure = (dateHeure.getHours()<10?'0':'') + dateHeure.getHours()+":"+(dateHeure.getMinutes()<10?'0':'') + dateHeure.getMinutes()+":"+(dateHeure.getSeconds()<10?'0':'') + dateHeure.getSeconds();
contenu = ""+heure+" : "+contenu+"\n";
setTimeout (() => {
logs.appendFile('./logs/logs.log', contenu, function (err) {
if (err) console.log('erreur avec les logs ! + '+err);
else {console.log("log ecrit");}
});
rss = heapUsed = heapTotal = contenu = dateHeure = heure = null;
},200);
}
les logs avec les infos mémoires : https://www.cjoint.com/c/KEut3bnBca3
Quelqu'un aurait-il une idée ??
Cordialement.