Partage
  • Partager sur Facebook
  • Partager sur Twitter

NodeJS arrêt setInterval

    19 mai 2021 à 23:54:04

    Bonjour,

    J'ai créé une petite applet qui mesure la température et la stocke dans une base de donnée. 

    J'utilise un setntervalle pour faire mes mesures périodiquement (toute les 5 minutes).

    Mais mon applet ne fait plus d'enregistrements au bout d'un certain moment.

    Je n'ai ni message derreurs ni bug, juste le setIntervalle qui ne s'éxécute plus.

    Cela tourne sur Raspberry pi 0 et raspian. C'est le seul applet de la carte.

    //dependances
    const Net = require('net');
    const sondeTemperature = require('ds18b20-raspi');
    const nodemailer = require('nodemailer');
    const logs = require('fs');
    const bdd = require('mysql'); //bdd
    
    //variables nécéssaires
    
    const listeSonde = sondeTemperature.list(); // recense la liste des capteurs de température disponible
    var boolTemperature = 0; // Si erreur avec la sonde alors passage à 1;
    const TempscooldownMail = 5; //sert pour empêcher le spam de mail, temps en minutes
    var cooldownMail = 0;
    var nbBoucle = 12;
    //en cas d'erreurs, les infos mails
    const transporter = nodemailer.createTransport(
    {
    	service: 'gmail',
    	auth:
    	{
    		user: '',
    		pass: ''
    	}
    });
    
    //tableau des données reçu et utiles
    var tabDonnee = new Array();
    
    setTimeout( ()=> {
    if(listeSonde.length < 1) // si pas de sondes trouvé
    {
    	boolTemperature = 1;
    	mailAlerte("sondeManquante");
    	erreurLogs("sondeManquante");
    	return;
    }
    else // si au moins 1 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.");
    
    let timerMinute = setInterval(() => {VerifMinute();}, 300000); //timer de vérification des minutes, boucle toute les 5 minutes. 60000
    
    function VerifMinute() // lancé toute les 5 minutes pour lire la température
    {
    	erreurLogs("verifminute lancé");
    	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)
    	{
    		
    		tabDonnee[1][1] = sondeTemperature.readC(tabDonnee[1][0]);
    		if((tabDonnee[1][1] < tabDonnee[1][4]) | (tabDonnee[1][1] > tabDonnee[1][3]))
    		{
    			mailAlerte("seuilTemperature");
    		}
    	}
    	if(cooldownMail > 0) cooldownMail = cooldownMail -1;
    	if(nbBoucle > 11)
    	{
    		nbBoucle = 0;
    		MesurePeriodiqueHeure();
    	}
    	else nbBoucle = nbBoucle +1;
    	
    	heure = temp = null;
    }
    function MesurePeriodiqueHeure() // lancé toute les heures pour enregistrer la mesure courante
    {
    	var contenu = "";
    	var dateHeure = new Date();
    	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)
    	{
    		var mySqlClient = bdd.createConnection(
    		{
    			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) 
    			{
    				mySqlClient.end();
    				mailAlerte("erreurBDD");
    				erreurLogs("erreur BDD : "+error);
    				return;
    			}
    			//erreurLogs(contenu);
    			contenu = date = heure = dateheure = null;
    		});
    		
    	}
    }
    
    function mailAlerte(erreur)
    {
    	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.\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\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, \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) // créé des logs et enregistre les infos mémoires.
    {
    	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('/home/pi/nodeJS/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);
    }
    

    Le code n'est pas optimisé, je cherche d'abord a le rendre fonctionnel.

    Je vais essayer d'en écrire un plus claire avec plus de commentaires.

    Quelqu'un sais pourquoi mon application s'arrête d'enregistrer ainsi ??

    Cordialement.

    -
    Edité par Noé22 20 mai 2021 à 0:01:00

    • Partager sur Facebook
    • Partager sur Twitter
      20 mai 2021 à 21:56:14

      Bonjour,

      comme dis plus haut, j'ai réécris mon code pour plus de lisibilité : 

      //dependances
      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);
      }
      

      voici mon fichier log de la nuit avec les ressources mémoires : https://www.cjoint.com/c/KEut3bnBca3

      Quelqu'un a t-il une iddée ?



      • Partager sur Facebook
      • Partager sur Twitter

      NodeJS arrêt setInterval

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown