Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[MQTT] state class de variable puissance à modifier
#1
Bonjour,

La nouvelle version de home assistant prend nativement en charge la puissance instantanée et l'affiche dans l'onglet énergie
Mais le sensor doit posséder la state_class "measurement"
or envoiMQTT.ino définit systématiquement la state_class à "total_increasing" (fonction DeviceToDiscover)

Il faudrait modifier la fonction pour que la bonne state_class soit associée aux unités de puissance ?

void DeviceToDiscover(String VarName, String TitleName, String Unit, String Class, String Round)
{
  char value[700];
  char DiscoveryTopic[120];
  char UniqueID[50];
  char ValTpl[60];
  char state_class[60];
  sprintf(DiscoveryTopic, "%s%s/%s_%s/%s", PrefixMQTT, SSR, MQTTdeviceName.c_str(), VarName.c_str(), "config");
  sprintf(UniqueID, "%s_%s", MQTTdeviceName.c_str(), VarName.c_str());
  sprintf(ValTpl, "{{ value_json.%s|default(0)|round(%s)}}", VarName.c_str(), Round.c_str());
  sprintf(state_class, "%s", "");
  if (Unit == "Wh" || Unit == "kWh")
  {
    sprintf(state_class, "\"state_class\":\"total_increasing\"%s,", state_class);
  }
  if (Unit == "W" || Unit == "kW")
  {
    sprintf(state_class, "\"state_class\":\"measurement\"%s,", state_class);
  }
  // Ajout de unit_class pour HA Core
  sprintf(value, "{\"name\": \"%s\",\"uniq_id\": \"%s\",\"stat_t\": \"%s\",\"device_class\": \"%s\",\"unit_of_meas\": \"%s\",\"unit_class\":\"%s\",%s\"val_tpl\": \"%s\",\"device\": %s, \"availability_topic\": \"%s\"}", TitleName.c_str(), UniqueID, StateTopic, Class.c_str(), Unit.c_str(), Class.c_str(), state_class, ValTpl, DEVICE, AvailableTopic);
  clientMQTT.publish(DiscoveryTopic, value);
}
Répondre

#2
OK pour la prochaine version 16.10, j'ai rajouté:

if (Unit == "W" || Unit == "kW")

  {
    sprintf(state_class, "\"state_class\":\"measurement\"%s,", state_class);
  }


André
Répondre

#3
(Il y a 3 heures)F1ATB a écrit : OK pour la prochaine version 16.10, j'ai rajouté:

if (Unit == "W" || Unit == "kW")

  {
    sprintf(state_class, "\"state_class\":\"measurement\"%s,", state_class);
  }


André

super!
je suis en train de modifier aussi un peu le code pour que les bonnes valeurs MQTT soient envoyées lorsquon est en uxix3.
Je fignole et je poste ça ici Smile

pour remonter en mqtt les données de tension et intensité des 3 phases :

- déplacer la déclaration des variables de source_uxix3 vers solar_router.ino

float Tension_M1, Tension_M2, Tension_M3, Intensite_M1, Intensite_M2, Intensite_M3;

- ajouter dans envoimqtt.ino :

dans void SendDataToHomeAssistant() :
if (Source == "UxIx3")
{
sprintf(value, "%s,\"Tension_M1\": %.1f, \"Intensite_M1\": %.1f,\"Tension_M2\": %.1f, \"Intensite_M2\": %.1f,\"Tension_M3\": %.1f, \"Intensite_M3\": %.1f, \"Frequence\":%.2f", value, Tension_M1, Intensite_M1, Tension_M2, Intensite_M2, Tension_M3, Intensite_M3, Frequence);
}

dans sendMQTTDiscoveryMsg_global()

if (Source == "UxIx3")
{
DeviceToDiscover("Tension_M1", "Tension p1", "V", "voltage", "2");
DeviceToDiscover("Intensite_M1", "Intensité p1", "A", "current", "2");
DeviceToDiscover("Tension_M2", "Tension p1", "V", "voltage", "2");
DeviceToDiscover("Intensite_M2", "Intensité p2", "A", "current", "2");
DeviceToDiscover("Tension_M3", "Tension p3", "V", "voltage", "2");
DeviceToDiscover("Intensite_M3", "Intensité p3", "A", "current", "2");
}


enfin j'en profite pour mettre une version améliorée de source uxix3 qui remonte les bonnes valeurs de consommation dans le reste du programme et qui fait les calculs en décalage de bits Smile

// *************************************************
// * Client lecture JSY-MK-333 * Triphasé *
// * Développement initial de Pierre F (Mars 2024) *
// * update PhDV61 Juin 2024 et Août 2024*
// *************************************************


void Setup_JSY333() {
MySerial.setRxBufferSize(SER_BUF_SIZE);
MySerial.begin(9600*2, SERIAL_8N1, RXD2, TXD2); //PORT DE CONNEXION AVEC LE CAPTEUR JSY-MK-333
}

void Requete_JSY333() {
int i;
if (RAZ_JSY) { //RAZ Message proposé par F6AAM
byte msg_send[] = { 0x01, 0x10, 0x00, 0x0C, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFA };
// Envoi commande raz sur le JSY-MK_333
for (i = 0; i < 13; i++) {
MySerial.write(msg_send[i]);
}
RAZ_JSY = false;
delay(500);
}
byte msg_send[] = { 0x01, 0x03, 0x01, 0x00, 0x00, 0x44, 0x44, 0x05 };
for (i = 0; i < 8; i++) {
MySerial.write(msg_send[i]);
}
}

void Lecture_JSY333() {
//float Tension_M1, Tension_M2, Tension_M3;
//float Intensite_M1, Intensite_M2, Intensite_M3;
float PVA_M_inst1, PVA_M_inst2, PVA_M_inst3;
float PW_inst1, PW_inst2, PW_inst3;

byte Lecture333[200];
bool injection;
bool sens1, sens2, sens3;
long delta_temps = 0;

Requete_JSY333();

int a = 0;
while (MySerial.available()) {
Lecture333[a] = MySerial.read();
a++;
}

if (a == 141) { //message complet reçu
delta_temps = (unsigned long)(millis() - Temps_precedent); // temps écoulé depuis le dernier appel
Temps_precedent = millis(); // on conserve la valeur du temps actuel pour le calcul précédent

Tension_M1 = ((Lecture333[3] << 8) + Lecture333[4]) / 100;
Tension_M2 = ((Lecture333[5] << 8) + Lecture333[6]) / 100;
Tension_M3 = ((Lecture333[7] << 8) + Lecture333[8]) / 100;

Intensite_M1 = float(((Lecture333[9] << 8) + Lecture333[10])) / 100;
Intensite_M2 = float(((Lecture333[11] << 8) + Lecture333[12])) / 100;
Intensite_M3 = float(((Lecture333[13] << 8) + Lecture333[14])) / 100;

sens1 = (Lecture333[104]) & 0x01;
sens2 = (Lecture333[104] >> 1) & 0x01;
sens3 = (Lecture333[104] >> 2) & 0x01;

if (sens1) { Intensite_M1 *= -1; }
if (sens2) { Intensite_M2 *= -1; }
if (sens3) { Intensite_M3 *= -1; }

injection = (Lecture333[104] >> 3) & 0x01; // si true, injection

// Lecture des Puissances actives de chacune des phases
PW_inst1 = float((Lecture333[15] << 8) + Lecture333[16]);
PW_inst2 = float((Lecture333[17] << 8) + Lecture333[18]);
PW_inst3 = float((Lecture333[19] << 8) + Lecture333[20]);

//Lecture des puissances apparentes de chacune des phases, qu'on signe comme le Linky
PVA_M_inst1 = float((Lecture333[35] << 8) + Lecture333[36]);
if (sens1) { PVA_M_inst1 = -PVA_M_inst1; }
PVA_M_inst2 = float((Lecture333[37] << 8) + Lecture333[38]);
if (sens2) { PVA_M_inst2 = -PVA_M_inst2; }
PVA_M_inst3 = float((Lecture333[39] << 8) + Lecture333[40]);
if (sens3) { PVA_M_inst3 = -PVA_M_inst3; }

if (injection) {
PuissanceS_M_inst = 0;
PuissanceI_M_inst = float((Lecture333[21] << 24) + (Lecture333[22] << 16) + (Lecture333[23] << 8) + Lecture333[24]);
PVAS_M_inst = 0;
PVAI_M_inst = abs(PVA_M_inst1 + PVA_M_inst2 + PVA_M_inst3); // car la somme des puissances apparentes "signées" est négative puisqu'en "injection" au global

// PhDV61 : on considère que cette puissance active "globale" a duré "delta_temps", et on l'intègre donc pour obtenir une énergie en Wh
Energie_jour_Injectee += ((float)delta_temps / 1000.0) * (PuissanceI_M_inst / 3600.0);
Energie_M_Injectee = Energie_jour_Injectee;

} else { // soutirage
PuissanceI_M_inst = 0;
PuissanceS_M_inst = float((Lecture333[21] << 24) + (Lecture333[22] << 16) + (Lecture333[23] << 8) + Lecture333[24]);
PVAS_M_inst = PVA_M_inst1 + PVA_M_inst2 + PVA_M_inst3;

// PhDV61 : on considère que cette puissance active "globale" a duré "delta_temps", et on l'intègre donc pour obtenir pour obtenir une énergie en Wh
Energie_jour_Soutiree += ((float)delta_temps / 1000.0) * (PuissanceS_M_inst / 3600.0);
Energie_M_Soutiree = Energie_jour_Soutiree;
}

MK333_dataBrute = "";
MK333_dataBrute = "<strong>Triphasé</strong>";

if (Intensite_M1 < 0)
MK333_dataBrute += "<br>Phase1 : " + String(Tension_M1) + "V x " + String(Intensite_M1) + "A = " + String(int(PVA_M_inst1)) + "VA</br>";
else
MK333_dataBrute += "<br>Phase1 : " + String(Tension_M1) + "V x +" + String(Intensite_M1) + "A = +" + String(int(PVA_M_inst1)) + "VA</br>";

if (Intensite_M2 < 0)
MK333_dataBrute += "<br>Phase2 : " + String(Tension_M2) + "V x " + String(Intensite_M2) + "A = " + String(int(PVA_M_inst2)) + "VA</br>";
else
MK333_dataBrute += "<br>Phase2 : " + String(Tension_M2) + "V x +" + String(Intensite_M2) + "A = +" + String(int(PVA_M_inst2)) + "VA</br>";

if (Intensite_M3 < 0)
MK333_dataBrute += "<br>Phase3 : " + String(Tension_M3) + "V x " + String(Intensite_M3) + "A = " + String(int(PVA_M_inst3)) + "VA</br>";
else
MK333_dataBrute += "<br>Phase3 : " + String(Tension_M3) + "V x +" + String(Intensite_M3) + "A = +" + String(int(PVA_M_inst3)) + "VA</br>";

if (PuissanceS_M_inst == 0)
MK333_dataBrute += "<br>Puissance active injectée : " + String(PuissanceI_M_inst) + "W</br>";
else
MK333_dataBrute += "<br>Puissance active soutirée : " + String(PuissanceS_M_inst) + "W</br>";

if (PVAS_M_inst == 0)
MK333_dataBrute += "<br>Puissance apparente injectée : " + String(PVAI_M_inst) + "VA</br>";
else
MK333_dataBrute += "<br>Puissance apparente soutirée : " + String(PVAS_M_inst) + "VA</br>";

if (PVA_M_inst1 != 0)
MK333_dataBrute += "<br>Facteur de puissance phase 1 : " + String(abs(PW_inst1 / PVA_M_inst1)) + "</br>";
if (PVA_M_inst2 != 0)
MK333_dataBrute += "<br>Facteur de puissance phase 2 : " + String(abs(PW_inst2 / PVA_M_inst2)) + "</br>";
if (PVA_M_inst3 != 0)
MK333_dataBrute += "<br>Facteur de puissance phase 3 : " + String(abs(PW_inst3 / PVA_M_inst3)) + "</br>";

MK333_dataBrute += "<br>Energie jour nette soutirée (Linky): " + String(Energie_jour_Soutiree) + "Wh</br>";
MK333_dataBrute += "<br>Energie jour nette injectée (Linky): " + String(Energie_jour_Injectee) + "Wh</br>";

MK333_dataBrute += "<br>Energie totale soutirée : " + String(Energie_M_Soutiree) + "Wh</br>";
MK333_dataBrute += "<br>Energie totale injectée : " + String(Energie_M_Injectee) + "Wh</br>";

Pva_valide = true;
filtre_puissance();
PuissanceRecue = true; //Reset du Watchdog à chaque trame du JSY reçue
EnergieActiveValide = true;
if (cptLEDyellow > 30) {
cptLEDyellow = 4;
}
} else {
StockMessage("Pas tout reçu, pas traité... nombre de données : " + String(a));
}
}
Répondre



Atteindre :


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

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