Réception données MQTT et temps réel

Oui @Grangean si node red occupe le port rs232 vous pouvez
faire sudo node-red-stop puis ensuite sudo node-red-start.

Ce qui est étrange c’est que j’ai l’impression qu’au départ je n’avais pas ces soucis de téléversement. Et puis c’était de plus en plus dur de téléverser … Vous me confirmez mes tests, je vous remercie. (il a fallu que je réinstalle complètement un système pour que je m’en rende compte !)
Donc je reviens à mon premier jeedom, et je teste vos codes !

Pour le fun j’aimerai bien voir la partie programmation du nodered !

Je n’utilise la COM de mes esp que pour le debug ou le téléversement par PC avec l’IDE Arduino alors je ne serais pas confirmer ou infirmer cela.

Pendant que j’y suis, je vais abuser de votre bienveillance. Je viens de quitter node-red et de le relancer. J’ai perdu mon flow (heureusement sauvegardé précédemment).
Comment je peux fixer ce pb, car je risque d’ arrêter/démarrer souvent pour tester vos codes.
tiens d’ailleurs j’ai perdu aussi les node installé (type InfluxDB).
@olive Je t’envoie le flow en MP

L’arrêt de node red flingue les flow ???
je fais une sauvegarde et je vérifie ça de suite je suis surpris :thinking:

Oui c’est ce que j’ai vu hier. Du coup je fais autrement, je déconnecte juste le serial le temps du télé versement.
Pareil quand je redémarre le raspberry, j’ai tendance à perdre les flow. J’ai cherché dans la doc et le fichier config comment être sûr que cela sauvegarde les flow mais je n’ai pas trouvé réellement.

Bonjour @olive
Ton code fonctionne très bien ! maintenant lequel je vais choisir entre le tien et celui de @PanoLyon ?
Ce que je lui disais, c’est qu’il faudrait que le code soit assez réactif puisqu’il vise à piloter les ballons ECS.

Sans vouloir vous embêter encore, quel que soit la tempo que vous me proposez, ces commandes dans la timeline prennent beaucoup de place, et je ne peux pas avoir une vue des changements de la journée (scénario, allumage, …).
Je n’ai que 20 min de visible dans la timeline, normal ?

Je vois aussi qu’avec cette tempo, les courbes dans grafana sont moins jolies. en y réfléchissant, il y aurait peut-être eu une solution au niveau de node-red : une temporisation pour l’envoie vers jeedom mais pas pour l’envoie dans la base de données dont se sert grafana pour les courbes.

En tout cas, je vais fixer le sujet comme solution, avec vos deux codes. Merci pour votre aide et votre réactivité. C’est un plaisir.

Voici le code de @PanoLyon qui fonctionne également :

                                 //--------PROGRAMME POUR OPTIMISER AUTOTONSOMMATION PHOTOVOLTAIQUE---------------------------------------
//---1ere partie c'est la  mesure des valeurs Volt_1 et Ampere_1---------------------------------------------------
//---2eme partie, Calculer les watts instantanés,les wattheures cumulés, les kWh et envoyer les valeurs sur un écran LCD
//---3eme partie, Gerer le servo moteur --------------------------------------------------------------------------
//---4eme Partie, Pour 2 autres pinces amperemetriques------------------------------------------------------------
//---5eme partie, gestion de differents affichages avec bouton poussoir sur un meme ecran LCD 2 lignes ---------------

//#include "RTClib.h"
//RTC_DS1307 rtc;

#include "EmonLib.h"             // 1 Pour inclure la librairie "EmonLib.h", aller dans le menu "croquis" puis "inclure une bibliothèque" 
// 1 puis "gérer les bibliothèques ". Une fois la librairie trouvée, appuyer sur "More info" puis " Installer"
EnergyMonitor emon1;             // 1 Creer une instance qui s'appelle emon1 (on s'en servira si on veut installer plusieurs pinces ampèremétriques)
EnergyMonitor emon2;             // 4 Idem que dessus pour une deuxième pince amperemetrique
EnergyMonitor emon3;             // 4 Idem que dessus pour une troisième pince amperemetrique

#include <Wire.h>                        // 2 inclure la librairie "wire.h" (si elle n'existe pas dans la bibliothèque, faire comme expliqué pour EmonLib.h
//#include <LiquidCrystal_I2C.h>           // 2 inclure la librairie "LiquidCrystal_I2C.h" 
////LiquidCrystal_I2C lcd(0x27, 16, 4);    // 2 définir l'adresse de l'écran LCD, le nombre de caractères et le nombre de lignes
//LiquidCrystal_I2C lcd(0x3f, 16, 2);      // 2 Si Le LCD ne fonctionne pas, alors mettre // sur la ligne précédente et enlever les // sur cette ligne

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//#include <Servo.h>                       // 3 inclure la librairie "Servo.h"
//Servo myservo;                           // 3 Création de l'objet Servo pour controler Servo
//float pos = 0;                           // 3 Creation de la variable (flottante)qui donnera la position du servo


const int led = 6;                       // 6  valeur finale auquel la led va s'allumer  de 0(éteint) à 250 (allumé à fond)
int intensite_led = 0;                   // 6  Variable intermédiaire  de l'intensité de la led

float w_instantane_in = 0;            // 2 Creation de la variable flottante "puissance instantanée" qui rentre (en watt) initialisée à la valeur 0
float kwh_cumule_in = 0;              // 2' Création de la variable flottante correspondant au Kilo Watt heure "consommé" cumulés initialisé à 0

float w_instantane_out = 0;           // 2 Creation de la variable flottante "puissance instantanée" qui sort (negative) en watt initialisée à la valeur 0
float kwh_cumule_out = 0;             // 2' Création de la variable flottante correspondant au Kilo Watt heure "surproduction" cumulés initialisé à 0

float w_Chauffe_Eau_1 = 0;             // 4 Creation de la variable flottante "puissance instantanée2" 2ième pince ampèrmétrique, initialisée à la valeur 0
float kwh_Chauffe_Eau_1 = 0;           // 4 Creation de la variable flottante "puissance cumulée2" qui rentre en Kilowattheure initialisée à la valeur 0

float w_Chauffe_Eau_2 = 0;             // 4 Creation de la variable flottante "puissance instantanée2" 2ième pince ampèrmétrique, initialisée à la valeur 0
float kwh_Chauffe_Eau_2 = 0;           // 4 Creation de la variable flottante "puissance cumulée2" qui rentre en Kilowattheure initialisée à la valeur 0

const int pin_bouton_changer_ecran=9;  //5 numéro de la pin du bouton poussoir qui sert à changer d'écran
int impulsion = 0;                     //5 creation de la variable impulsion
int compteur_impulsion = 1;            //5 compteur du nombre d'impulsion effectué sur le bouton poussoir, variable qui va servir pour le changement d'affichage


unsigned long previous_millis = 0;   // 2 création de la variable "previous_millis" qui garde en mémoire le temps qui s'écoule en millièmes de seconde"


/*
 * MODIFICATION1
 */
long REFRESH_TIME = 1;                               //Temps souhaité de rafraichissement entre deux mesures VOIR MODIFICATION2 DANS void setup() pour l'unité
long REFRESH_TIME_MEM=0;                              //Memoire du temps au dernier envoie de la mesure
bool TRANSMIT = true;                                //variable Global permettant de passer outre la tempo de transmission si elle est passée à true, est à true pour le 1er tour de programme
/*
* 
*/

//-----------------------INITIALISATION DU PROGRAMME-------------------------------------------------

void setup()
{
  Serial.begin(115200);                 // 1 Création du port série pour que l'arduino puisse envoyer des infos vers l'ordinateur

//if (! rtc.begin()) {
//    Serial.println("Couldn't find RTC");
//    Serial.flush();
//    abort();
//  }
//
//  if (! rtc.isrunning()) {
//    Serial.println("RTC is NOT running, let's set the time!");
//    // When time needs to be set on a new device, or after a power loss, the
//    // following line sets the RTC to the date & time this sketch was compiled
//    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//    // This line sets the RTC with an explicit date & time, for example to set
//    // January 21, 2014 at 3am you would call:
//    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
//  }
//
  emon1.voltage(2, 228, 1.7);      //avec 5V   // 1 Initialisation du Voltage (Pin A2, Valeur à changer pour etalonnage (+/-357 pour 6v et +/- 190 pour 12v))
 // emon1.voltage(0, 125, 1.7);      //avec 3.3V   // 1 Initialisation du Voltage (Pin A2, Valeur à changer pour etalonnage (+/-357 pour 6v et +/- 190 pour 12v))
  emon1.current(1, 88);          //avec 3.3V   // 1 Initialisation du Courant en ampère ( Pin A1, Valeur à changer lors de l'etalonnage)
 // emon1.current(1, 1);             // 1 Initialisation du Courant en ampère ( Pin A1, Valeur à changer lors de l'etalonnage)

    emon2.voltage(2, 228, 1.7);         // 4 Initialisation du Voltage (Pin A2, Valeur à changer pour etalonnage, phase_shift)
    emon2.current(3, 28.5);             // 4 Initialisation du Courant en ampère ( Pin A3, Valeur à changer lors de l'etalonnage)
  //
    emon3.voltage(2, 228, 1.7);         // 4 Initialisation du Voltage (Pin A2, Valeur à changer pour etalonnage, phase_shift)
    emon3.current(0, 28.5);             // 4 Initialisation du Courant en ampère ( Pin A6, Valeur à changer lors de l'etalonnage)

 // lcd.init();                         // 2 initialisation de l'afficheur LCD
lcd.begin(16,2);
  //myservo.attach(5);                   // 3 On attache l'objet servo à la Pin D5

 pinMode(led, OUTPUT);                // 6 La broche sur lequel est la variable led est une sortie 

 pinMode(pin_bouton_changer_ecran, INPUT_PULLUP);   //5 Le bouton poussoir est une entrée forcé à 0V si on appuis pas et à 5V  si on appuie

/*
* MODIFICATION2
*/
  REFRESH_TIME = REFRESH_TIME * 1000 * 60;    // Passage de la tempo en minute
/*
* 
*/

}

//----------------------- DEMARRAGE DE LA BOUCLE----------------------------------------------------

void loop()
{

//DateTime now = rtc.now();

//int heure!now.hour();
//Serial.println(now.hour(), DEC);
//Serial.println(heure);

//if (now.hour() >= 10 and now.minute() >=41)
//{
//  Serial.println("condtion horaire oui");
//}
//else
//{
//  Serial.println("condtion horaire non");
//}

  
  float puissance_reelle1 = emon1.realPower;   //1 creation de la variable flottante "puissance reelle" qui existe dans la librairie sous "emon1.realPower"
//   Serial.print("{\"puiss\":");
//   Serial.print(puissance_reelle1);                                                         
//   Serial.println("}");
   //delay(500);
    float puissance_reelle2 = emon2.realPower;   //4 creation de la variable flottante "puissance reelle" qui existe dans la librairie sous "emon1.realPower"
    float puissance_reelle3 = emon3.realPower;   //4 creation de la variable flottante "puissance reelle" qui existe dans la librairie sous "emon1.realPower"

 // float verif_voltage    = emon1.Vrms;        //1 creation de la variable "volts moyen" (mesurable avec un voltmètre pour l'etalonnage)
 // float verif_ampere     = emon1.Irms;        //1 creation de la variable "Ampères Moyen" (mesurable avec une pince ampèremétrique pour l'etalonnage))

  emon1.calcVI(20, 2000);                     // 1 Demande a Emonlib de tout calculer,  (puissance relle, volts moyen, ampère moyen et facteur de puissance)
  emon2.calcVI(20,2000);                      // 4 idem qu'au dessus mais pour la deuxième pince ampèrmétrique (si on met 40 au lieu de 20, ca va moins vite)
  emon3.calcVI(20,2000);                      // 4 idem qu'au dessus mais pour la troisième pince ampèrmétrique (et du coup c'est plus lisible sur le LCD)

  //emon1.serialprint();                      // (1) Si on ecrit cette ligne , toutes les valeurs calculées precedemment sont envoyées vers l'ordinateur

  //--------------------------Etalonnage des volts et ampères sans LCD--------------------------------------

//  Serial.print("Est-ce le bon voltage? ");      // 1 envoyer vers l'ordinateur le texte " Est-ce le bon voltage? "
//  Serial.print(verif_voltage);                  // 1 envoyer vers l'ordinateur la valeur "verif_voltage (Vrms)"
//  Serial.print(" V  ");                         // 1 envoyer vers l'ordinateur le caractère "V"
//  Serial.print(verif_ampere);                   // 1 envoyer vers l'ordinateur la valeur "verif_voltage (Vrms)"
//  Serial.println(" A ");                          // 1 envoyer vers l'ordinateur le caractère "A"
//  Serial.println(intensite_led);
//delay(1000);
  //----------------POUR AVOIR LES W, Wh et kWh de l'élélectricité qui rentre et de l'électricité qui sort de ma maison------------------

  if (puissance_reelle1 >= 0)                      // 2 Si la puissance reelle est positive, (c'est que je consomme et qu'a priori il n'y a pas de soleil)
  {
    w_instantane_in = puissance_reelle1;      // 2 alors on dit que la puissance instantanée entrante (in) est egale à la puissance reelle.
    w_instantane_out = 0;                     // 2 dans ces conditions de consommation (positive) , la valeur de la surproduction est nulle.

    kwh_cumule_in = kwh_cumule_in + puissance_reelle1 * (millis() - previous_millis) / 3600000 / 1000;
    // 2 La valeur cumulée consommée (entrante) = La valeur cumulée consommée précédente,
    // 2 plus la puissance reelle multipliée par le temps écoulé entre millis et previous millis
    // 2 que divise 3600 (nb secondes / heure) et encore par 1000 car millis compte les millièmes de seconde
    // 2 et encore par mille car ce sont les kWh et non les Wh qui m'intêresse.
  }

  else                                             // 2 SINON (c'est que la puissance_reelle est négative)
  {
    w_instantane_in = 0;                       // 2 idem au dessus
    w_instantane_out = puissance_reelle1; // 2 idem au dessus

    kwh_cumule_out = kwh_cumule_out + puissance_reelle1 * (millis() - previous_millis) / 3600000 / 1000;
  }

  // ----------------------Pour avoir les w, wh et kwh production solaire et consommation chauffe eau------

  
      w_Chauffe_Eau_1 = puissance_reelle2;        //4 idem au dessus mais la pince ampèremetrique branché sur la conso du chauffe eau
      kwh_Chauffe_Eau_1 = kwh_Chauffe_Eau_1 + puissance_reelle2 * (millis() - previous_millis) / 3600000/ 1000;

      w_Chauffe_Eau_2 = puissance_reelle3;        //4 idem au dessus mais la pince ampèremetrique branché sur la conso du chauffe eau
      kwh_Chauffe_Eau_2 = kwh_Chauffe_Eau_2 + puissance_reelle3 * (millis() - previous_millis) / 3600000/ 1000;


  previous_millis = millis();               // 2 Demandons a la variable previous_millis de garder en memoire la valeur de millis (le tps qui s'écoule)

 //-------------------------------------Si il y a des Watts , balance en dans le chauffe eau---------------------------------

  if (puissance_reelle1 <= 100 && intensite_led < 230) //6 si la puissance sonsommée est inférieur à 1w, et que la led n'est mas à son maximum
  {intensite_led += 5;                               // 6 augmenter l'intensité lumineuse de 5
  analogWrite(led, intensite_led);}                  //6 la led va s'éclairer au niveau de la valeur de intensite_led
  //delay(1000);

  //Serial.println(intensite_led);
  if(puissance_reelle1 >= 100 && intensite_led > 0)  //6 inversement, si la conso en watt est supérieur à 100 et et que la led n'est pas à son minimum
  {intensite_led -= 5;                               //6 diminue alors l'intensité de la led
  analogWrite(led, intensite_led);}                 // 6 la led va s'éclairer au niveau de la valeur de intensite_led

  // --------------------ECRIRE SUR LCD ET POUR CHANGER LES VALEUR DuLCD AVEC UN BOUTON POUSSOIR------------------------------------------------

  //lcd.backlight();                // 2 Allumer l'écran LCD
  lcd.clear();                    // 2 rafraichir l'écran LCD ( efface les données précédentes)


   impulsion = digitalRead(pin_bouton_changer_ecran);               //5 Demande à "impulsion" de prendre la valeur de "pin_bouton_changer_ecran"
    if (impulsion == 0) compteur_impulsion = compteur_impulsion + 1; //5 On incrémente le compteur d'impulsion s'il y a une impulsion sur le bouton
  //Serial.print(compteur_impulsion);
    if (compteur_impulsion == 1)                                     //5 Si le compteur d'impulsion est égale à 1 on affiche le premier écran
          {
  //-----Ecran n°1:-------------------------------

  //1ere ligne, watt entrant et watts sortant----
  lcd.setCursor(0, 0);               // 4 positionner le curseur sur la ligne 1 et à gauche
  lcd.print("In ");   // 4 ecrire "In " pour comprendre qu'il s'agit de la consommation
  lcd.print(w_instantane_in, 0);     // 4 puis écrire la valeur positive de la consommation au compteur EDF avec 2 chiffre derière la virgule
  lcd.setCursor(9, 0);               // 4 rester sur la ligne 1 mais positionner le curseur sur le caractère 8
  lcd.print(w_instantane_out, 0);     // 4 ecrire la valeur de w_instantane_out (c'est la surproduction) avec 2 chiffre derière la virgule



  //2eme ligne, Watt solaire et watts chauffe eau
  lcd.setCursor(2, 1);              // 4 positionner le curseur sur la ligne 2 et à gauche
  lcd.print(w_Chauffe_Eau_1, 0);          // 4 puis écrire la valeur de la surproduction visible par EDF avec les compteurs electroniques (sans les virgules)
  lcd.setCursor(9, 1);              // 4 Rester sur la ligne 2 mais curseur position 8
  lcd.print(w_Chauffe_Eau_2, 0);      // 4 puis écrire à la suite la valeur de la surproduction en Wh avec un chiffre derrière la virgule
          }
  //
   else if (compteur_impulsion == 2) //5 Sinon s'il est égale à 2 on affiche l'écran numéro 2
          {
          //Serial.print(compteur_impulsion);  
          // -----ECRAN N°2:-------------------------------
          //1ere ligne, kWh entrant et KkWh sortant--------
          lcd.setCursor(0, 0);            // 4 positionner le curseur sur la ligne 1 et à gauche
          lcd.print("2 ");                // 4 ecrire "2" pour comprendre que nous sommes sur l'écran n°2
          lcd.print(kwh_cumule_in,4);     // 4 puis écrire la valeur de la consommation en kWh avec 4 chiffres derrière la virgule
          lcd.setCursor(8, 0);            // 4 rester sur la ligne 1 mais positionner le curseur sur le caractère 9
          lcd.print(" ");                 // 4 ecrire " " pour séparer les deux valeur de cette ligne
          lcd.print(kwh_cumule_out,4);    // 4 ecrire la valeur des Watts cumulé en kWh, c'est la valeur de la surproduction
  
          //2eme ligne, KWh solaire et kWh chauffe eau
          lcd.setCursor(2, 1);              // 4 positionner le curseur sur la ligne 2 et position 2
          lcd.print(kwh_Chauffe_Eau_1,4);         // 4 puis écrire la valeur de la production cumulée de mes panneaux solaire en kWh
          lcd.setCursor(8, 1);              // 4 rester sur la ligne 2 mais positionner le curseur en position 2
          lcd.print(" ");                 // 4 ecrire " " pour séparer les deux valeur de cette ligne
          lcd.print(kwh_Chauffe_Eau_2,4);     // 4 puis écrire la consomation cumulée de mon chauffe eau en Kwh
          }
  
   else if (compteur_impulsion == 3)      // 5 si on a appuié 3 fois sur le bouton poussoir,
          {
           // Serial.print(compteur_impulsion);
          compteur_impulsion = 1;          // 5 alors on remet le compteur à 0 et on retrouve l'écran n°1
          }

/*
* MODIFICATION3
*/
  if ((millis() - REFRESH_TIME_MEM > REFRESH_TIME)||(TRANSMIT == true)){
/*
 *
*/
          
  Serial.print(w_instantane_in);
  Serial.print(";");
  Serial.print(w_instantane_out);
  Serial.print(";");
  Serial.print(w_Chauffe_Eau_1);
  Serial.print(";");
  Serial.print(w_Chauffe_Eau_2);
  Serial.print(";");
  Serial.print(kwh_cumule_in);
  Serial.print(";");
  Serial.print(kwh_cumule_out);
  Serial.print(";");
  Serial.print(kwh_Chauffe_Eau_1);
  Serial.print(";");
  Serial.print(kwh_Chauffe_Eau_2);
  Serial.print(";");
  Serial.print(intensite_led);
  Serial.print("\n");

/*
* MODIFICATION4
*/
            REFRESH_TIME_MEM=millis();   //reset temporisation
            TRANSMIT=false;    //1er tour de programme passé ou transmission effectuée.
  }
/*
* 
*/
  
  delay(1000);


}                                 // FIN DU PROGRAMME

Oui ça efface le flow, je commence la semaine avec une nouvelle découverte il faut que je fouine ça …

Timeline c’est bien ce que vous vous voyez quand vous demandez les événements en temps réelle ?

Ferme tout de suite ton flow node red ma un peut forcé a travailler …
(c’est une bonne chose)
aujourd’hui ton code est sur le principe
lecture serial port arduino —> decodage —> mqtt —> jeedom
on devrait pouvoir faire
lecture serial port arduino —> decodage —> jeedom (info virtuel)
et ainsi oublier mqtt.

en même temps dans node red on doit pouvoir choisir la tempo des éléments qui doivent être instantané ou pas.

Oui c’est ça !

Je vous ai envoyez la réponse plus en avant il y a 5 jours pour ne plus les avoir, ce n’est pas ce que vous vouliez ?

Bon ce matin j’ai jouer avec node red pour tester la possibilité d’echaper a mqtt
je n’avait pas d’arduino avec le système de de Barnabé mais le principe est le même
tout le principe est sur l’etiquette Envoi sur virtuel Jeedom
Resultat :
Capture d’écran du 2020-05-25 12-21-19
Capture d’écran du 2020-05-25 12-13-31

Détails :
l’objet et un : http request
méthode : GET
l’url doit être au format suivant

http://IP:PORT/core/api/jeeApi.php?plugin=virtual&apikey=APIKEY&type=virtual&id=IDVIRTUEL&value={{{payload}}}

a personnaliser :
IP:PORT , APIKEY , IDVIRTUEL

1 « J'aime »

Si, mais cela ne fonctionne pas : les cases « suivre dans la timeline » ne sont pas cochées et pourtant on les voit dans la Time Line.
Avoir si avec la proposition de @olive de se passer de mqtt, ça résout le pb.

Content que vous ayez pu jouer ainsi :blush:
Je veux bien essayer ça un de ces 4, quel serait l’avantage ?

Éviter MQTT pour alléger le truc
a cela on peut ajouter une temporisation des données qui n’on pas besoin d’être temps réel.

Tu peut même juste faire un test sur le flow barnabe en parallèle sans tout cassé

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.