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


Messages dans ce sujet
JSYRemoteSender en tant que source - par Chris - 17-04-2025, 09:33 AM
RE: JSYRemoteSender en tant que source - par piamp - 24-04-2025, 10:38 AM
RE: JSYRemoteSender en tant que source - par Chris - 24-04-2025, 11:32 AM

Atteindre :


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