Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Intégration shelly PRO em
#1
Bonjour,
Je me suis lancé dans la conception du routeur.
Problème rencontré, je dispose d'un Shelly Pro Em.
Hors la requête HTTP à effectuer est différente d'un shelly EM classique, et la réponse JSON également.
J'ai dû modifier le code source dans le fichier Source_ShellyEm.ino

Voici les modifications effectuées pour un shelly PRO em.
Si cela pouvait être intégré aux prochaines version se serait top.



La requête : http://IP_SHELLY/rpc/shelly.getstatus

Modification du fichier Source_ShellyEm.ino

Déclaration à ajouter pour la récupération
String tmp;

Modification de la requête http :
String url = "/rpc/Shelly.GetStatus";

Modification de la partie commenté Monophasé

Code :
//Monophasé

    //***************** ADD PERSO : PRO EM ******************
    ShEm_dataBrute = "<strong>Monophasé</strong><br>" + Shelly_Data;
  
    tmp=PrefiltreJson("em1:"+ String(Voie),":",Shelly_Data);

    //Récupération partie pince sur la voie paramètré
    Pw = ValJson("act_power",tmp);
    voltage = ValJson("voltage",tmp);
    pf = ValJson("pf",tmp);
    pf = abs(pf);
    if (pf > 1) pf = 1;
    if (Voie == voie) {  //voie du routeur
      if (Pw >= 0) {
          PuissanceS_M_inst = Pw;
          PuissanceI_M_inst = 0;
          if (pf > 0.01) {
            PVAS_M_inst = PfloatMax(Pw / pf);
          } else {
            PVAS_M_inst = 0;
          }
          PVAI_M_inst = 0;
        } else {
          PuissanceS_M_inst = 0;
          PuissanceI_M_inst = -Pw;
          if (pf > 0.01) {
            PVAI_M_inst = PfloatMax(-Pw / pf);
          } else {
            PVAI_M_inst = 0;
          }
          PVAS_M_inst = 0;
        }
        tmp=PrefiltreJson("em1data:"+ String(Voie),":",Shelly_Data);
        Energie_M_Soutiree = myLongJson("total_act_energy",tmp);
        Energie_M_Injectee = myLongJson("total_act_ret_energy",tmp);
        PowerFactor_M = pf;
        Tension_M = voltage;
        Pva_valide=true;
      } else {  // voie secondaire
        if (LissageLong) {
          PwMoy2 = 0.2 * Pw + 0.8 * PwMoy2;  //Lissage car moins de mesure sur voie secondaire
          pfMoy2 = 0.2 * pf + 0.8 * pfMoy2;
          Pw = PwMoy2;
          pf = pfMoy2;
        }
        if (Pw >= 0) {
          PuissanceS_T_inst = Pw;
          PuissanceI_T_inst = 0;
          if (pf > 0.01) {
            PVAS_T_inst = PfloatMax(Pw / pf);
          } else {
            PVAS_T_inst = 0;
          }
          PVAI_T_inst = 0;
        } else {
          PuissanceS_T_inst = 0;
          PuissanceI_T_inst = -Pw;
          if (pf > 0.01) {
            PVAI_T_inst = PfloatMax(-Pw / pf);
          } else {
            PVAI_T_inst = 0;
          }
          PVAS_T_inst = 0;
        }
        tmp=PrefiltreJson("em1data:"+ String(Voie),":",Shelly_Data);
        Energie_T_Soutiree = myLongJson("total_act_energy",tmp);
        Energie_T_Injectee = myLongJson("total_act_ret_energy",tmp);
        PowerFactor_T = pf;
        Tension_T = voltage;
      }


NB : Voici le format du JSON
Code :
{
  "ble": {},
  "cloud": {
    "connected": true
  },
  "em1:0": {
    "id": 0,
    "current": 2.454,
    "voltage": 239.9,
    "act_power": 226.5,
    "aprt_power": 590.1,
    "pf": 0.62,
    "freq": 50,
    "calibration": "factory"
  },
  "em1:1": {
    "id": 1,
    "current": 1.782,
    "voltage": 239.9,
    "act_power": 426.4,
    "aprt_power": 429.6,
    "pf": 0.99,
    "freq": 50,
    "calibration": "factory"
  },
  "em1data:0": {
    "id": 0,
    "total_act_energy": 995515.84,
    "total_act_ret_energy": 106191.28
  },
  "em1data:1": {
    "id": 1,
    "total_act_energy": 477522.54,
    "total_act_ret_energy": 756.38
  },
  "eth": {
    "ip": null
  },
  "modbus": {},
  "mqtt": {
    "connected": false
  },
  "switch:0": {
    "id": 0,
    "source": "WS_in",
    "output": false,
    "temperature": {
      "tC": 37,
      "tF": 98.6
    }
  },
  "sys": {
    "mac": "34987A6XXXXX",
    "restart_required": false,
    "time": "17:13",
    "unixtime": 1718205196,
    "uptime": 419677,
    "ram_size": 243368,
    "ram_free": 117336,
    "fs_size": 524288,
    "fs_free": 192512,
    "cfg_rev": 22,
    "kvs_rev": 0,
    "schedule_rev": 15,
    "webhook_rev": 9,
    "available_updates": {},
    "reset_reason": 3
  },
  "wifi": {
    "sta_ip": "192.168.1.XX",
    "status": "got ip",
    "ssid": "Freebox-XXXX",
    "rssi": -50
  },
  "ws": {
    "connected": false
  }
}
Répondre
#2
Bien mais jusqu'à présent je n'utilisais plus ArduinoJson, car sur de grosses données cela plantait. C'est pourquoi j'ai fait mes propres routines pour extraire les données.

Cdlt
Répondre
#3
Wink 
(12-06-2024, 07:10 PM)F1ATB a écrit : Bien mais jusqu'à présent je n'utilisais plus ArduinoJson, car sur de grosses données cela plantait. C'est pourquoi j'ai fait mes propres routines pour extraire les données.

Cdlt

Ok, je trouvais ça plus pratique.
Vous pouvez intégrer le modèle pro dans les versions à venir ?

Au passage, merci pour votre travail ! Wink
Répondre
#4
oui, on verra pour le proposer
Répondre
#5
(12-06-2024, 07:18 PM)F1ATB a écrit : oui, on verra pour le proposer

Le shelly PRO 3 EM, modèle triphasé, à la même structure JSON d'après la doc pour info.
Même requête HTTP également.
Répondre
#6
(12-06-2024, 05:49 PM)Raphael591 a écrit : Bonjour,
Je me suis lancé dans la conception du routeur.
Problème rencontré, je dispose d'un Shelly Pro Em.
Hors la requête HTTP à effectuer est différente d'un shelly EM classique, et la réponse JSON également.
J'ai dû modifier le code source dans le fichier Source_ShellyEm.ino

Voici les modifications effectuées pour un shelly PRO em.
Si cela pouvait être intégré aux prochaines version se serait top.

J'ai ajouté la librairie arduinoJson pour faciliter la lecture des données dans le Json retourné par la requête.

La requête : http://IP_SHELLY/rpc/shelly.getstatus

Modification du fichier Source_ShellyEm.ino

Déclaration pour facilité la lecture JSON
  JsonObject em1data;
  JsonObject em1;


Modification de la requête http :
String url = "/rpc/Shelly.GetStatus";

Lecture des infos :
//Alimentation doc JSON
StaticJsonDocument<1536> doc;
DeserializationError error = deserializeJson(doc, Shelly_Data);
if (error) {
  StockMessage("Shelly PRO em deserializeJson() failed");
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}


//Récupération des valeurs
em1 = doc["em1:"+ String(voie)];
Pw = em1["act_power"];
voltage = em1["voltage"];
pf = em1["pf"];


em1data = doc["em1data:"+ String(voie)];
Energie_M_Soutiree = int(em1data["total_act_energy"]);
Energie_M_Injectee = int(em1data["total_act_ret_energy"]);


NB : Voici le format du JSON

{
  "ble": {},
  "cloud": {
    "connected": true
  },
  "em1:0": {
    "id": 0,
    "current": 2.454,
    "voltage": 239.9,
    "act_power": 226.5,
    "aprt_power": 590.1,
    "pf": 0.62,
    "freq": 50,
    "calibration": "factory"
  },
  "em1:1": {
    "id": 1,
    "current": 1.782,
    "voltage": 239.9,
    "act_power": 426.4,
    "aprt_power": 429.6,
    "pf": 0.99,
    "freq": 50,
    "calibration": "factory"
  },
  "em1data:0": {
    "id": 0,
    "total_act_energy": 995515.84,
    "total_act_ret_energy": 106191.28
  },
  "em1data:1": {
    "id": 1,
    "total_act_energy": 477522.54,
    "total_act_ret_energy": 756.38
  },
  "eth": {
    "ip": null
  },
  "modbus": {},
  "mqtt": {
    "connected": false
  },
  "switch:0": {
    "id": 0,
    "source": "WS_in",
    "output": false,
    "temperature": {
      "tC": 37,
      "tF": 98.6
    }
  },
  "sys": {
    "mac": "34987A6XXXXX",
    "restart_required": false,
    "time": "17:13",
    "unixtime": 1718205196,
    "uptime": 419677,
    "ram_size": 243368,
    "ram_free": 117336,
    "fs_size": 524288,
    "fs_free": 192512,
    "cfg_rev": 22,
    "kvs_rev": 0,
    "schedule_rev": 15,
    "webhook_rev": 9,
    "available_updates": {},
    "reset_reason": 3
  },
  "wifi": {
    "sta_ip": "192.168.1.XX",
    "status": "got ip",
    "ssid": "Freebox-XXXX",
    "rssi": -50
  },
  "ws": {
    "connected": false
  }
}

Bonjour,
Un grand merci pour ce code ! 
J'ai également un Shelly PRO EM-50 et jusqu'à présent, je devais passer par Jeedom pour retransférer les données Pw et pf en MQTT vers le routeur qui ne les décodait pas nativement.
Après avoir intégré ces lignes, je reçois maintenant directement ces valeurs (+toutes les autres), et ca va bien désengorger le cœur domotique qui devait 'faire la passe', ce qui prenait un peu de ressource tout de même juste pour cette tâche ingrate. 
Et de plus, en cas d'avarie sur Jeedom (plantage ou autre), cela n'aura plus aucune incidence sur le fonctionnement autonome du routeur, ce qui n'est pas négligeable non plus... 
Encore merci, en attendant son intégration 'officielle' dans une version à venir ! Shy
_________________________________________________
Routeur Solaire en v10.00 (modifié pour intégration d'un Shelly PRO EM-50). 
Pilotage d'un cumulus de 3kW + Jeedom v4.4.7 + Station solaire 3,5kW
Répondre
#7
J'ai repris mon code, pour reprendre les procédures d'André pour la lecture des JSON.
Plus de bibliothèque à ajouter.
J'ai corrigé également une erreur qui provoquait une un problème sur la seconde sonde.

Remplacer le pavé commenté "//Monophasé" du fichier Source_ShellyEm.ino :

Déclaré au début du document la variable tmp.
//ADD PERSO : AJOUT VARIABLE pour la lecture des infos EM PRO
String tmp;

Code :
//Monophasé

    //***************** ADD PERSO : PRO EM ******************
    ShEm_dataBrute = "<strong>Monophasé</strong><br>" + Shelly_Data;
   
    tmp=PrefiltreJson("em1:"+ String(Voie),":",Shelly_Data);

    //Récupération partie pince sur la voie paramètré
    Pw = ValJson("act_power",tmp);
    voltage = ValJson("voltage",tmp);
    pf = ValJson("pf",tmp);
    pf = abs(pf);
    if (pf > 1) pf = 1;
    if (Voie == voie) {  //voie du routeur
      if (Pw >= 0) {
          PuissanceS_M_inst = Pw;
          PuissanceI_M_inst = 0;
          if (pf > 0.01) {
            PVAS_M_inst = PfloatMax(Pw / pf);
          } else {
            PVAS_M_inst = 0;
          }
          PVAI_M_inst = 0;
        } else {
          PuissanceS_M_inst = 0;
          PuissanceI_M_inst = -Pw;
          if (pf > 0.01) {
            PVAI_M_inst = PfloatMax(-Pw / pf);
          } else {
            PVAI_M_inst = 0;
          }
          PVAS_M_inst = 0;
        }
        tmp=PrefiltreJson("em1data:"+ String(Voie),":",Shelly_Data);
        Energie_M_Soutiree = myLongJson("total_act_energy",tmp);
        Energie_M_Injectee = myLongJson("total_act_ret_energy",tmp);
        PowerFactor_M = pf;
        Tension_M = voltage;
        Pva_valide=true;
      } else {  // voie secondaire
        if (LissageLong) {
          PwMoy2 = 0.2 * Pw + 0.8 * PwMoy2;  //Lissage car moins de mesure sur voie secondaire
          pfMoy2 = 0.2 * pf + 0.8 * pfMoy2;
          Pw = PwMoy2;
          pf = pfMoy2;
        }
        if (Pw >= 0) {
          PuissanceS_T_inst = Pw;
          PuissanceI_T_inst = 0;
          if (pf > 0.01) {
            PVAS_T_inst = PfloatMax(Pw / pf);
          } else {
            PVAS_T_inst = 0;
          }
          PVAI_T_inst = 0;
        } else {
          PuissanceS_T_inst = 0;
          PuissanceI_T_inst = -Pw;
          if (pf > 0.01) {
            PVAI_T_inst = PfloatMax(-Pw / pf);
          } else {
            PVAI_T_inst = 0;
          }
          PVAS_T_inst = 0;
        }
        tmp=PrefiltreJson("em1data:"+ String(Voie),":",Shelly_Data);
        Energie_T_Soutiree = myLongJson("total_act_energy",tmp);
        Energie_T_Injectee = myLongJson("total_act_ret_energy",tmp);
        PowerFactor_T = pf;
        Tension_T = voltage;
      }
Répondre
#8
Bien, merci. Je garde cela dans un coin pour une prochaine version.

André
Répondre
#9
Bonjour,
Je confirme pour l'avoir testé que ce code fonctionne sans avoir besoin de la librairie 'ArduinoJson.h' pour un Shelly EM PRO-50 en monophasé, ce qui simplifie la modification.

J'ai néanmoins constaté une petite erreur me semble-t-il.
En effet, toujours dans le fichier Source_ShelleyEm.ino d'origine, à la ligne 33 :

Code :
String url = "/emeter/" + String(Voie);

Il faut la remplacer par celle-ci (qui était déjà l'objet de la première version de cette modification) :

Code :
String url = "/rpc/shelly.getstatus";

Sinon, aucune info ne remontera.

Et si comme moi vous avez une erreur dans le signe de la puissance (où - = puissance injectée, + = puissance soutirée), il suffit d'inverser le signe de Pw ici en ligne 108 :

Code :
Pw = -ValJson("act_power",tmp); // Inversion du signe de la puissance : Pw négatif = puissance injectée, Pw positif = puissance soutirée

Encore merci !
_________________________________________________
Routeur Solaire en v10.00 (modifié pour intégration d'un Shelly PRO EM-50). 
Pilotage d'un cumulus de 3kW + Jeedom v4.4.7 + Station solaire 3,5kW
Répondre
#10
(26-06-2024, 12:36 PM)DanielJ a écrit : Bonjour,
Je confirme pour l'avoir testé que ce code fonctionne sans avoir besoin de la librairie 'ArduinoJson.h' pour un Shelly EM PRO-50 en monophasé, ce qui simplifie la modification.

J'ai néanmoins constaté une petite erreur me semble-t-il.
En effet, toujours dans le fichier Source_ShelleyEm.ino d'origine, à la ligne 33 :

Code :
String url = "/emeter/" + String(Voie);

Il faut la remplacer par celle-ci (qui était déjà l'objet de la première version de cette modification) :

Code :
String url = "/rpc/shelly.getstatus";

Sinon, aucune info ne remontera.

Et si comme moi vous avez une erreur dans le signe de la puissance (où - = puissance injectée, + = puissance soutirée), il suffit d'inverser le signe de Pw ici en ligne 108 :

Code :
Pw = -ValJson("act_power",tmp); // Inversion du signe de la puissance : Pw négatif = puissance injectée, Pw positif = puissance soutirée

Encore merci !

Ah oui j'ai oublié de redonner ce point. Je pense réédité le premier post proprement. Merci.
Répondre


Atteindre :


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