Note de ce sujet :
  • Moyenne : 1 (1 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Compatibilité compteur connecté EM06P (Meross, Refoss)
#21
Bonjour,
j'ai déplacé mon routeur à côté de ma box internet Wifi, le niveau WIFI est maintenant à -50dBm.
Maintenant, les pages s'affichent plus rapidement. La Led jaune pulse normalement toutes les 2s.
Cependant, lorsque je change entre les différentes pages, on dirait que j'arrive à surcharger le routeur et fini par planté.

J'ai fait un test, j'ai chargé la page "Donnée brutes", et je ne change plus de page.
Maintenant, j'ai la Led qui pulse normalement et l"ESP ON" est à 1h10min.

J'ai 2 mesures de températures et 1 action.

Avez-vous une idée de ce qu'il pourrait se passer?
Merci
Installation : 1 routeur fixe F1ATB en V17.19 en mode SSR pour chauffe-eau avec thermostat électronique
Photovoltaïque : 3 kWp : 3* (2 *500w + Micro onduleur Hoymiles HMS-1000W-2T) 
Domotique : F1atb + Home Assistant / REFOSS EM06P & MQTT
Répondre

#22
Bonjour,
le problème était les fichiers Export qui saturaient la mémoire et faisant plante l'ESP32.
J'ai sûrement du générer plein d'erreurs lorsque je faisais mes tests avec MQTT.

Maintenant, je suis surpris de la vitesse de chargement des pages du routeur :-)

Tout fonctionne bien, je n'ai plus qu'à m'atteler à la programmation des actions.

En espérant que mes recherches pourront en aider d'autres.

Encore merci André pour ton travail.
Installation : 1 routeur fixe F1ATB en V17.19 en mode SSR pour chauffe-eau avec thermostat électronique
Photovoltaïque : 3 kWp : 3* (2 *500w + Micro onduleur Hoymiles HMS-1000W-2T) 
Domotique : F1atb + Home Assistant / REFOSS EM06P & MQTT
Répondre

#23
Bonjour,
j'ai modifié le programme avec l'aide de l'IA Claude afin d'y intégrer mon compteur EM06P. Je me suis inspiré de ce qui était fait pour le Shelly Pro3Em.
J'ai fait les modifs en dur avec une pince voie 1 et l'autre voie 4; ca peut ne pas correspondre pour une autre personne.
Je mets ici le .ino concernant le compteur EM06P:
Code :
//*********************************************************************
// Variante EM06P                                                    *
// Adaptation basée sur un exemple réel de réponse JSON de l'EM06P :  *
//                                                                     *
// {"status":[                                                        *
//   {"id":1,"current":2.319,"voltage":228.614,"power":-155.988,      *
//    "pf":-0.29,"year_energy":294.99,"year_ret_energy":-259.035,     *
//    "month_energy":...,"week_energy":...,"day_energy":...},         *
//   {"id":2, ...}, ... jusqu'à {"id":6, ...}                         *
// ]}                                                                  *
//                                                                     *
// L'EM06P ne fournit PAS de compteur d'énergie cumulé depuis          *
// toujours (pas de "total_act_energy" façon Shelly). Le champ le     *
// plus proche est "year_energy" (kWh, flottant) mais il repart à     *
// zéro chaque 1er janvier.                                           *
// ********************************************************************
// * Paramétrage des voies pour le EM06P :                             *
// *   - EnphaseSerial (0 à 5) = numéro de la voie/pince du routeur   *
// *     (voie "M"). L'EM06P a 6 voies, mais leurs "id" JSON vont     *
// *     de 1 à 6 -> conversion +1 faite dans le code.                 *
// *   - VOIE_SECONDAIRE_EM06P_ID (constante ci-dessous) = voie "T"   *
// *     (ex: production PV). Fixée en dur à l'id 4 : adaptez cette   *
// *     valeur si votre câblage change.                               *
// *                                                                    *
// * IMPORTANT : contrairement au Shelly (qui nécessitait une requête *
// * HTTP séparée par voie, d'où l'ancienne logique d'alternance sur  *
// * plusieurs cycles), l'EM06P renvoie TOUTES les voies en une seule *
// * requête. On extrait donc M et T à CHAQUE appel, pour une         *
// * régulation plus réactive (plus d'alternance qui ne rafraîchissait*
// * la voie du routeur qu'une fois sur 5 cycles environ).            *
// ********************************************************************

// id JSON (1 à 6) de la voie secondaire T - à adapter si besoin
const int VOIE_SECONDAIRE_EM06P_ID = 4;

// Extrait le sous-objet JSON {"id":N, ...} d'une chaîne "status":[...]
// Hypothèse : les objets de voie ne contiennent que des champs scalaires
// (pas de sous-objet imbriqué), donc la première "}" après le "id":N
// correspond bien à la fin de l'objet de cette voie.
String ExtraitVoieEM06P(int id, String &data) {
  String cle = "\"id\":" + String(id) + ",";
  int debut = data.indexOf(cle);
  if (debut < 0) return "";
  debut = data.lastIndexOf("{", debut);
  int fin = data.indexOf("}", debut);
  if (fin < 0) return "";
  return data.substring(debut, fin + 1);
}

// Extrait les grandeurs (Pw, voltage, pf, énergies jour/année) d'un
// sous-objet de voie déjà isolé (résultat de ExtraitVoieEM06P).
void LectureVoieEM06P(String &tmp, float &Pw, float &voltage, float &pf,
                       long &energieSoutireeWh, long &energieInjecteeWh,
                       long &jourSoutireeWh, long &jourInjecteeWh) {
  // Convention confirmée par observation terrain : power négatif = injection
  // réelle, power positif = soutirage réel. Pas d'inversion nécessaire.
  Pw = ValJson("power", tmp);
  voltage = ValJson("voltage", tmp);
  pf = abs(ValJson("pf", tmp));
  if (pf > 1) pf = 1;

  // Compteur d'énergie "année" en kWh -> converti en Wh (cf. limitation
  // en tête de fichier : ce compteur repart à zéro chaque année).
  float yearEnergy = ValJson("year_energy", tmp);
  float yearRetEnergy = ValJson("year_ret_energy", tmp);
  energieSoutireeWh = (long)(abs(yearEnergy) * 1000.0);
  energieInjecteeWh = (long)(abs(yearRetEnergy) * 1000.0);

  // Compteur d'énergie "jour" (kWh -> Wh), fourni directement par l'EM06P,
  // remis à zéro chaque minuit par l'appareil lui-même : utilisé tel quel,
  // sans calcul de delta (voir EnergieQuotidienne() dans le sketch principal).
  float dayEnergy = ValJson("day_energy", tmp);
  float dayRetEnergy = ValJson("day_ret_energy", tmp);
  jourSoutireeWh = (long)(abs(dayEnergy) * 1000.0);
  jourInjecteeWh = (long)(abs(dayRetEnergy) * 1000.0);
}

void LectureEM06P() {
  String EM06P_Data = "";
  String tmp;

  WiFiClient clientESP_RMS;
  String host = IP2String(RMSextIP);

  const int NB_VOIES = 6;  // EM06P : 6 voies monophasées indépendantes
  int idM = (EnphaseSerial.toInt() % NB_VOIES) + 1;  // id JSON de la voie routeur (1 à 6)
  int p;
  unsigned long timeout = millis();

  // id=65535 = id spécial qui renvoie le statut des 6 voies en une requête
  String url = "/rpc/Em.Status.Get?id=65535";

  if (!clientESP_RMS.connect(host.c_str(), 80, 3000)) {
    delay(500);
    if (!clientESP_RMS.connect(host.c_str(), 80, 3000)) {
      delay(100);
      clientESP_RMS.stop();
      StockMessage("connection to EM06P failed : " + host);
      delay(200);
      return;
    }
  }

  clientESP_RMS.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");

  // Lecture robuste : on attend la fermeture de la connexion par le serveur
  // (Connection: close) plutôt que de s'arrêter dès qu'il n'y a momentanément
  // plus de données disponibles - la réponse peut arriver en plusieurs paquets.
  bool gotData = false;
  timeout = millis();
  while (millis() - timeout < 5000) {
    while (clientESP_RMS.available()) {
      EM06P_Data += (char)clientESP_RMS.read();
      timeout = millis();  // on relance le délai tant que des données arrivent
      gotData = true;
    }
    if (!clientESP_RMS.connected() && !clientESP_RMS.available()) {
      break;  // le serveur a fermé la connexion et il n'y a plus rien à lire
    }
  }
  clientESP_RMS.stop();
  if (!gotData) {
    StockMessage("client EM06P Timeout ! : " + host);
    return;
  }
  p = EM06P_Data.indexOf("{");
  if (p < 0) {
    StockMessage("EM06P : aucune accolade '{' trouvée dans la réponse");
    filtre_puissance();
    PuissanceRecue = true;
    return;
  }
  EM06P_Data = EM06P_Data.substring(p);

  String brute = "";

  // --- Voie M (routeur) --- lue à chaque appel
  tmp = ExtraitVoieEM06P(idM, EM06P_Data);
  if (tmp != "") {
    brute += "<strong>EM06P voie M (id " + String(idM) + ")</strong><br>" + tmp + "<br>";

    float Pw, voltage, pf;
    long energieSoutireeWh, energieInjecteeWh, jourSoutireeWh, jourInjecteeWh;
    LectureVoieEM06P(tmp, Pw, voltage, pf, energieSoutireeWh, energieInjecteeWh, jourSoutireeWh, jourInjecteeWh);

    if (Pw >= 0) {
      PuissanceS_M_inst = Pw;
      PuissanceI_M_inst = 0;
      PVAS_M_inst = (pf > 0.01) ? PfloatMax(Pw / pf) : 0;
      PVAI_M_inst = 0;
    } else {
      PuissanceS_M_inst = 0;
      PuissanceI_M_inst = -Pw;
      PVAI_M_inst = (pf > 0.01) ? PfloatMax(-Pw / pf) : 0;
      PVAS_M_inst = 0;
    }
    Energie_M_Soutiree = energieSoutireeWh;
    Energie_M_Injectee = energieInjecteeWh;
    EnergieJour_M_Soutiree = jourSoutireeWh;
    EnergieJour_M_Injectee = jourInjecteeWh;
    PowerFactor_M = pf;
    Tension_M = voltage;
    Pva_valide = true;
  } else {
    StockMessage("EM06P : voie M (id " + String(idM) + ") introuvable dans la réponse JSON");
  }

  // --- Voie T (secondaire, ex: PV) --- lue à chaque appel elle aussi
  tmp = ExtraitVoieEM06P(VOIE_SECONDAIRE_EM06P_ID, EM06P_Data);
  if (tmp != "") {
    brute += "<strong>EM06P voie T (id " + String(VOIE_SECONDAIRE_EM06P_ID) + ")</strong><br>" + tmp;

    float Pw, voltage, pf;
    long energieSoutireeWh, energieInjecteeWh, jourSoutireeWh, jourInjecteeWh;
    LectureVoieEM06P(tmp, Pw, voltage, pf, energieSoutireeWh, energieInjecteeWh, jourSoutireeWh, jourInjecteeWh);

    if (LissageLong) {
      PwMoy2 = 0.2 * Pw + 0.8 * PwMoy2;
      pfMoy2 = 0.2 * pf + 0.8 * pfMoy2;
      Pw = PwMoy2;
      pf = pfMoy2;
    }
    if (Pw >= 0) {
      PuissanceS_T_inst = Pw;
      PuissanceI_T_inst = 0;
      PVAS_T_inst = (pf > 0.01) ? PfloatMax(Pw / pf) : 0;
      PVAI_T_inst = 0;
    } else {
      PuissanceS_T_inst = 0;
      PuissanceI_T_inst = -Pw;
      PVAI_T_inst = (pf > 0.01) ? PfloatMax(-Pw / pf) : 0;
      PVAS_T_inst = 0;
    }
    Energie_T_Soutiree = energieSoutireeWh;
    Energie_T_Injectee = energieInjecteeWh;
    EnergieJour_T_Soutiree = jourSoutireeWh;
    EnergieJour_T_Injectee = jourInjecteeWh;
    PowerFactor_T = pf;
    Tension_T = voltage;
  } else {
    StockMessage("EM06P : voie T (id " + String(VOIE_SECONDAIRE_EM06P_ID) + ") introuvable dans la réponse JSON");
  }

  ShEm_dataBrute = brute;

  filtre_puissance();
  PuissanceRecue = true;
  EnergieActiveValide = true;  // les deux voies sont lues à chaque appel, plus besoin d'alternance
  if (cptLEDyellow > 30) {
    cptLEDyellow = 4;
  }
}


Mes valeurs sont bien remontés sur la page d'accueil.
Je pense qu'il faut encore nettoyer le programme.
Cependant, la régulation semble moins stable que lorsque j'avais mes données de compteurs reçues via MQTT (voir PJ).
Je ne peux plus tester à cette heure, à voir les prochains jours.
Est-ce que quelqu'un a une idée d'où pourrait venir le problème?

Voici tout le programme en téléchargement:
https://www.grosfichiers.com/iauCewnwBBa


En espérant que ma version puisse aider un autre utilisateur d'EM06P ;-)


Pièces jointes Miniature(s)
   
Installation : 1 routeur fixe F1ATB en V17.19 en mode SSR pour chauffe-eau avec thermostat électronique
Photovoltaïque : 3 kWp : 3* (2 *500w + Micro onduleur Hoymiles HMS-1000W-2T) 
Domotique : F1atb + Home Assistant / REFOSS EM06P & MQTT
Répondre



Atteindre :


Utilisateur(s) parcourant ce sujet :
1 visiteur(s)

Moteur MyBB, © 2002-2026 Melroy van den Berg.