Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
JSYRemoteSender en tant que source
#1
Bonjour,

Mathieu Carbou propose une solution pour lire et transmettre des mesures effectuées par des JSY-MK-xxx: https://github.com/mathieucarbou/MycilaJ.../RemoteUDP
Plusieurs modèles sont supportés et l'envoi des données est effectué par broadcast udp.

On peut facilement intégrer sa solution en tant que source F1ATB.
Les intérêts sont multiples:
- charge très légère au niveau du routeur (lecture asynchrone, pas d'obligation d'avoir 2 cœurs finalement)
- pas de limite au nombre de routeurs utilisables: il n'y a pas de notion de routeur maître puisque x routeurs peuvent recevoir les données en même temps
- compatible avec ce qui est déjà en place pour ceux qui ont un routeur dédié à la lecture dans leur tableau 
- open source

La récupération des données est plutôt simple (je n'exploite qu'une pince, mais on peut facilement ajouter la 2ème)
Code :
#include <Arduino.h>
#include <AsyncUDP.h>
#include <WiFi.h>

#include <ArduinoJson.h>  // https://github.com/bblanchon/ArduinoJson
#include <FastCRC32.h>    // https://github.com/RobTillaart/CRC

// #define MYCILA_UDP_MSG_TYPE_JSY_DATA 0x01 // old json format
#define MYCILA_UDP_MSG_TYPE_JSY_DATA 0x02 // supports all JSY models
#define MYCILA_UDP_PORT              53964

AsyncUDP udp;

float _Tension_M, _Intensite_M, _Energie_M_Soutiree, _Energie_M_Injectee, _PowerFactor_M, _PuissanceS_M_inst, _PuissanceI_M_inst;
int _PVAS_M_inst, _PVAI_M_inst;

void Setup_remoteJSY() {

    udp.onPacket([](AsyncUDPPacket packet) {
    // buffer[0] == MYCILA_UDP_MSG_TYPE_JSY_DATA (1)
    // buffer[1] == size_t (4)
    // buffer[5] == MsgPack (?)
    // buffer[5 + size] == CRC32 (4)

    size_t len = packet.length();
    uint8_t* buffer = packet.data();

    if (len < 5 || buffer[0] != MYCILA_UDP_MSG_TYPE_JSY_DATA)
      return;

    uint32_t size;
    memcpy(&size, buffer + 1, 4);

    if (len != size + 9)
      return;

    // crc32
    FastCRC32 crc32;
    crc32.add(buffer, size + 5);
    uint32_t crc = crc32.calc();

    if (memcmp(&crc, buffer + size + 5, 4) != 0)
      return;
    
    /*
      "channel2": {
        "frequency": 49.98,
        "voltage": 226.3977,
        "current": 15.8607,
        "active_power": 3473.812,
        "reactive_power": 915.2476,
        "apparent_power": 3592.36,
        "power_factor": 0.967,
        "active_energy": 1144,
        "active_energy_imported": 1144,
        "resistance": 13.80898,
        "dimmed_voltage": 219.0201,
        "nominal_power": 3711.781,
        "thdi_0": 26.34706
      }
      */

    JsonDocument doc;
    deserializeMsgPack(doc, buffer + 5, size);

    // Données générale de la Maison
    _Tension_M = doc["channel2"]["voltage"];
    _Intensite_M = doc["channel2"]["current"];
    float pw = doc["channel2"]["active_power"];
    _Energie_M_Soutiree = doc["channel2"]["active_energy_imported"];
    float pf = doc["channel2"]["power_factor"];
    _Energie_M_Injectee = doc["channel2"]["active_energy_returned"];
    pf = abs(pf);
    if (pf > 1) pf = 1;
    _PowerFactor_M = pf;
    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;
    }
   
    filtre_puissance();
    PuissanceRecue = true; // Reset du Watchdog à chaque trame reçue
    EnergieActiveValide = true;
    Pva_valide = true;
    if (cptLEDyellow > 30) {
      cptLEDyellow = 4;
    }

  });

    
    udp.listen(MYCILA_UDP_PORT);
}

void LectureRemoteJSY() {
  Tension_M = _Tension_M;
  Intensite_M = _Intensite_M;
  Energie_M_Soutiree = _Energie_M_Soutiree;
  Energie_M_Injectee = _Energie_M_Injectee;
  PowerFactor_M = _PowerFactor_M;
  PuissanceS_M_inst = _PuissanceS_M_inst;
  PuissanceI_M_inst = _PuissanceI_M_inst;
  PVAS_M_inst = _PVAS_M_inst;
  PVAI_M_inst = _PVAI_M_inst;
}


Pour le setup / lecture, j'ai simplement modifié une source existante (v 12.06)
Code :
  if (Source == "Enphase") {
    Setup_remoteJSY();
  }

Code :
      if (Source == "Enphase") {
        LectureRemoteJSY();
          LastRMS_Millis = millis();
          PeriodeProgMillis = 150; 
      }

Il faudrait bien évidement faire une source dédiée, modifier la page paramètres et la vue des données brutes.

Si ça peut vous être utile..
Répondre
#2
C'est intéressant, mais quitte a utiliser un appareil de mesure dédié autant prendre directement un shelly?
Répondre
#3
Ca peut intéresser ceux qui ont déjà un routeur dédié avec pince JSY.
L'avantage du shelly c'est qu'il ne prend qu'un module dans le tableau. Je ne sais pas combien de clients il peut supporter. L'intérêt du système de Mathieu, c'est que les infos sont broadcastées en udp = > que tu aies 1 client ou 50 les infos seront traitées à la même vitesse.
Répondre


Atteindre :


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