Du désordre dans les datas compteur virtuel electrique

Posez ici vos questions d'utilisation, de configuration de DomoticZ, de bugs, de conseils sur le logiciel lui même dans son utilisation et son paramétrage.
Des forums spécifiques sont ouverts ci-dessous pour regrouper les différents sujets.
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Du désordre dans les datas compteur virtuel electrique

Message par knasson »

bonjour,

depuis quelques jours j'enregistre mes données de production Solaire (Injection) sur un compteur electrique virtuel que j'ai crée et qui est alimenté par un script toutes les 5 minutes.
jusqu'a hier tout allait bien ...
et la depuis cette nuit bim je ne sais pas ce qui s'est passé
1)les graphiques indiquent un historique sur 3 jours alors que précédemment c'était 24h.
2) les valeurs c et v sont inversées (réponse a la commande:http://raspberrypi:8080/json.htm?type=g ... ange=month)
3) comment remettre de l'ordre dans tout ca? (j'ai vidé le cache, rebooté le pi, redémarré domoticz..)
4) j'ai remarque un reset a zéro du compteur a minuit ?? (est ce que ca peut venir de là*?)
Pièces jointes
Capture d’écran 2021-04-10 090758.jpg
Capture d’écran 2021-04-10 090758.jpg (19.97 Kio) Consulté 3070 fois
Dernière modification par knasson le 10 avr. 2021, 12:23, modifié 1 fois.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Modération

Message par Keros »

Merci d'éditer le titre du sujet afin qu'il soit en rapport avec les questions posées.

Pour cela, remonter au premier message et cliquer sur le petit bouton crayon en haut à droite. Le champ titre est accessible.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
adv
Messages : 580
Inscription : 02 févr. 2016, 13:54
Contact :

Re: Au secours!

Message par adv »

Salut, donc tu dis alimenter le P1 virtuel par un script mais.... tu cites pas le script :|

Et puis d'où viennent les données de base (la prod) ? (n'as tu pas connecté ton compteur élec de production via un convertisseur USB sur la téléinfo ?, ne serait-ce pas là la soluce la plus simple)

Je suis pas expert mais si tu veux de l'aide va falloir en dire plus des fois qu'un costaud voit ce qui cloche...

A+
Raspberry pi 3 - Domoticz 2024.4 | Piface v.2 + Téléinfo + RFXtrx433E
sondes Oregon | motorisations Somfy Yslo Flex 2 RTS
prises chacon, wifi | Sonoff easyESP, Tasmota, Espurna | ParadoxMG5050
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Re: Du désordre dans les datas compteur virtuel electrique

Message par knasson »

Pour Info voila ce que j'avais avant ce problème
Pièces jointes
Capture d’écran 2021-04-06 193626.jpg
Capture d’écran 2021-04-06 193626.jpg (136.24 Kio) Consulté 3035 fois
Capture d’écran 2021-04-06 193626.jpg
Capture d’écran 2021-04-06 193626.jpg (136.24 Kio) Consulté 3035 fois
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Re: Du désordre dans les datas compteur virtuel electrique

Message par knasson »

Et voila ce que j'ai depuis ce matin...Alors que je n'ai rien touché...
Pièces jointes
Capture d’écran 2021-04-10 122721.jpg
Capture d’écran 2021-04-10 122721.jpg (150.78 Kio) Consulté 3033 fois
higgins91
Messages : 669
Inscription : 17 nov. 2016, 11:06

Re: Du désordre dans les datas compteur virtuel electrique

Message par higgins91 »

Ce que je vois c'est que tu passes de 15-18kw a 4000kw donc les valeurs 15-18kw sont très basses sur le graphique...
Dz version : 2024.7
Rpi 4 avec dongle téléinfo, GPIO pour le moment !
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Re: Du désordre dans les datas compteur virtuel electrique

Message par knasson »

Oui mais les bonnes valeurs de production sont 17-18:kWh et le 4000kwh c'est la valeur du compteur , mais c'est une anomalie qui n'a rien à faire ici.
Jusqu'à maintenant j'avais les valeurs de production journalière c'est a dire différence de compteur ( j -(j-1)) qui s'affichaient tranquillement sur le graphique et ce matin je découvre cette anomalie.
C'est l'objet de mon post...
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Re: Du désordre dans les datas compteur virtuel electrique

Message par knasson »

Bonjour,
tout est en ordre...
Pour ceux que mes tribulations sur domoticz intéressent, pour l'anomalie compteur sur la conso mensuelle je suis intervenu sur la donnée dans la base domoticz.db, table Meter_Calendar pour remettre la bonne valeur que j'avais calculée a la main.
Je crois connaitre l'origine de dérèglement, c'est une entrée à 0 sur la base a minuit le Vendredi soir qui a mis le souk dans mon compteur. Après comment l'empêcher? Je ne sais pas encore si vous avez des idées je suis preneur.

Pour l'affichage 24 dernières heures au lieu de 7 derniers jour (qui affiche 3 jours mais le graphique devient illisible) je ne sais pas trop comment j'ai fait ( j'ai mis le log des capteurs a 1 jour au lieu de 7 dans les parametres, mais je ne suis pas sur que ce soit ca, car la modification n'a pas été immédiate).Mais ca marche. Merci de confirmer l'influence de ce paramètre..
Bon dimanche ..
Pièces jointes
Capture d’écran 2021-04-11 080248.jpg
Capture d’écran 2021-04-11 080248.jpg (149.97 Kio) Consulté 2967 fois
knasson
Messages : 245
Inscription : 26 mars 2021, 08:59

Re: Du désordre dans les datas compteur virtuel electrique

Message par knasson »

bonjour,

Je dois admettre que la solution de corriger les datas manuellement dans la base de données domoticz ca commence a être un peu pénible.
Je dois donc trouver l'origine de ces données qui sont entrées a zero dans la BD domoticz.
mon installation trés simple:
-j'ai 2 compteurs linky 1 pour la conso et 1 pour la prod de mes panneaux solaires.
-un raspberrypi 4 sur disque dur USB 500 Go (je n'utilise pas les cartes SD a cause des risques "d'usure")
-un interface connecté sur les broches IO du raspberrypi qui utilise l'UART du RPI avec l'interface ttyAMA0 et qui captent les datas du mode historique du linky "consommation a 1200 bauds
-un interface USB pour Serial To TTL avec un opto coupleur de chez tindie qui utilise l'interface ttyUSB0 et capte les datas du mode "standard" à 9600 bauds et suit ma production solaire.

je n'ai jusqu'à maintenant pas de problème d'acquisition sur l'interface du compteur "conso" (interface /dev/ttyAMA0) et j'utilise le plugin Téléinfo intégré a Domoticz.
Par contre sur le l'interface du compteur de production solaire (/dev/ttyUSB0) j'ai des zéros qui sont entrés dans la BD. et comme je l'explique plus haut c'est ennuyeux car ca fout en l'air la consommation journalière (voir quelques post plus avant.)
là pour la mise a jour de ce compteur j'utilise un script écrit en C que m' a passé js-martin qui fonctionne très bien chez lui mais qui a un peu plus de mal chez moi.
En fait dans la trame téléinfo "standard" il n'y a que 2 étiquettes qui nous intéresse pour la production a savoir
EAIT pour énergie totale injectée
SINST valeur puissance injectée instantanée.
EAIT est la valeur "compteur" c'est a dire celle qui est totalisée elle ne peut qu'augmenter et ne peut pas soudain passer par zero.
Or je pense que le script en C utilisé aurait besoin d'un verrouillage software a ce niveau là.
je joins le script , je connais rien en C mais je devine qu' il y a peut être une motif "facile" a faire pour garantir que la valeur de EAIT ne soit jamais inferieure a la précédente valeur captée.

Code : Tout sélectionner


Code source C :

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <limits.h>
#include <sys/time.h>
#include <curl/curl.h>


//--------------------------------------------------
// DONNEES A MODIFIER EN FONCTION DE LA CONFIGURATION SOUHAITEE
//--------------------------------------------------
// Port Serie et Baud Rate
// Délimiteur (normalement 0x09 à 9600 bauds et 0x20 à 1200 bauds)
// Requête JSON pour Domoticz (CHANGER LE IDX AVEC LE NUMERO DE DEVICE)
//--------------------------------------------------
const char* SERIAL_PORT = "/dev/ttyUSB0";
const speed_t BAUD_RATE = B9600;
const char DEMILITER = 0x09;
const char* JSON_HEADER = "http://ip_pi:8080/json.htm?type=command&param=udevice&idx=735&nvalue=0&svalue=";
//--------------------------------------------------



/* Number of consecutive characters to read (max = 255) */
const unsigned int BUFFER_SIZE = 255;
/* Max number of characters in one line (<= BUFFER SIZE) */
const unsigned int MAX_LINE_SIZE = 150;
/* Min number of characters in one line (<= MAX_LINE_SIZE) */
const unsigned int MIN_LINE_SIZE = 5;

typedef struct {
   unsigned int EAST;
   unsigned int EAIT;
   unsigned int SINSTS;
   unsigned int SINSTI;
} Teleinfo;

typedef struct {
   int value;
   unsigned int elapsed_seconds;
} DomoticzDevice;


Teleinfo teleinfo = { .EAST = 0, .EAIT = 0, .SINSTS = 0, .SINSTI = 0 };
DomoticzDevice EDF = { .value = 0, .elapsed_seconds = 0 };

unsigned int send_message = 0; 
struct timeval tv1; struct timezone tz1;
struct timeval tv2; struct timezone tz2;

int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0)
    {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS7;         /* 7-bit characters */
    tty.c_cflag |= PARENB;     /* parity enabled & even */
    tty.c_cflag &= ~CSTOPB;     /* 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    /* read characters, with max delay of half second to receive a char */
    tty.c_cc[VMIN] = BUFFER_SIZE;
    tty.c_cc[VTIME] = 5;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) 
    {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

int isCheckSumOk(char* line)
{
   unsigned int checksum_expected = 0;
   unsigned int checksum_real = 0;
   unsigned int i;

   checksum_expected = line[strlen(line) - 1];
   for (i = 0; i <= strlen(line) - 2; i++)
   {
      checksum_real += line[i];
   }
   checksum_real = (checksum_real & 0x3F) + 0x20;

   if (checksum_expected != checksum_real)
   {
      //printf("ERROR --> Checksum failed on line: \"%s\"\n", line);
      unsigned char *p;
      unsigned int linelen = strlen(line);
      for (p = line; linelen-- > 0; p++)
         //printf(" 0x%x", *p);
      //printf("\n");
      return -1;
   }

   return 0;
}

int strToUL(char* str)
{
   unsigned int val = 0;
   char *endptr;
   errno = 0;
   val = strtoul(str, &endptr, 10);
   if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) 
   {
      printf("ERROR --> Cannot convert to ul the string: \"%s\"\n", str);
      return -1;
   }
   else if (endptr == str)
   {
      printf("ERROR --> Cannot convert to ul an empty string: \"%s\"\n", str);
      return -1;
   }
   return (int)val;
}

int sendUrl(char* url)
{
   int ret = -1;
    CURL *curl;
    CURLcode res;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, url);
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
      curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //Prevent "longjmp causes uninitialized stack frame" bug
      curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate");
      curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);
        //curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        //curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK)
        {
         printf("ERROR --> Cannot send curl url: \"%s\"\n", url);
        }
        else
        {
         ret = 0;
      }

        curl_easy_cleanup(curl);
    }
    else
    {
      printf("ERROR --> Cannot init curl\n");
   }
   return ret;
}

int processLine(char* line)
{
   char label [MAX_LINE_SIZE];
   char elem1 [MAX_LINE_SIZE];
   char elem2 [MAX_LINE_SIZE];
   int val;
   unsigned int start = 0;
   unsigned int i = 0;
   // Find next elem
   label[0] = '\0';
   for (i = start; i <= strlen(line) - 2; i++)
   {
      // Find the delimiter
      if (line[i] == DEMILITER)
      {
         memcpy(label, &line[start], i-start);
         label[i-start] = '\0';
         break;
      }
   }
   // Find next elem
   start = i+1;
   elem1[0] = '\0';
   for (i = start; i <= strlen(line) - 2; i++)
   {
      // Find the delimiter
      if (line[i] == DEMILITER)
      {
         memcpy(elem1, &line[start], i-start);
         elem1[i-start] = '\0';
         break;
      }
   }
   // Find next elem
   start = i+1;
   elem2[0] = '\0';
   for (i = start; i <= strlen(line) - 2; i++)
   {
      // Find the delimiter
      if (line[i] == DEMILITER)
      {
         memcpy(elem2, &line[start], i-start);
         elem2[i-start] = '\0';
         break;
      }
   }

   //printf("DEBUG --> New line: %s - %s - %s\n", label, elem1, elem2);
   // Save value
//   if(strcmp(label, "EAST") == 0) {
//      val = strToUL(elem1);
//      if (val != -1) teleinfo.EAST = (unsigned int)val;
//      else return -1;
//   } else 
        if(strcmp(label, "EAIT") == 0) {
      val = strToUL(elem1);
      if (val != -1) teleinfo.EAIT = (unsigned int)val;
      else return -1;
   }
//   else if(strcmp(label, "SINSTS") == 0) {
//      val = strToUL(elem1);
//      if (val != -1) teleinfo.SINSTS = (unsigned int)val;
//      else return -1;
//   }
   else if(strcmp(label, "SINSTI") == 0) {
      val = strToUL(elem1);
      if (val != -1) teleinfo.SINSTI = (unsigned int)val;
      else return -1;
   }
}

int main()
{
    //freopen("out.txt", "a", stdout);
    int fd;
    int wlen;
    unsigned char line[MAX_LINE_SIZE];
    unsigned int linelen = 0;
    unsigned int pos = 0;
    fd = open(SERIAL_PORT, O_RDONLY | O_NOCTTY | O_SYNC);
    if (fd < 0)
    {
        printf("Error opening %s: %s\n", SERIAL_PORT, strerror(errno));
        return -1;
    }

   /* Get current time */
   gettimeofday(&tv1, &tz1);
   gettimeofday(&tv2, &tz2);

    /* Open serial port */
    set_interface_attribs(fd, BAUD_RATE);

    /* Receive characters */
    do
    {
        unsigned char buf[BUFFER_SIZE];
        int rdlen;
        int first_line = 1;

        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0)
        {
         int i = 0;
         while (i < rdlen)
         {
            // Discard all special characters
            const char c = buf[i];
            if (((c >= 0x00) && (c <= 0x01)) || ((c >= 0x04) && (c <= 0x08)))
            {
               //printf("DEBUG --> Char 0x%x discarded in line: \"%s\"\n", c, line);
               i++;
               continue;
            }

            // Get character
            line[pos] = c;

            // If line ending is found
            if (((c >= 0x02) && (c <= 0x03)) || ((c >= 0x0a) && (c <= 0x0f)))
            {
               // Close string
               line[pos] = 0;
               linelen = pos;
               pos = 0;

               // Discard first line as it may be truncated
               if (first_line)
               {
                  first_line = 0;
               }
               // Discard lines too small
               else if (linelen < MIN_LINE_SIZE)
               {
                  // Nothing to do
                        //printf("WARNING --> Line discarded because too small: \"%s\"\n", line);
               }
               // Discard incoherent lines
               else if (line[linelen-2] != DEMILITER)
               {
                  //printf("ERROR --> Ending delimiter not found on line: \"%s\"\n", line);
               }
               else
               {
#ifdef DISPLAY_LINE_STRING
                  //printf("Read %d: \"%s\"\n", linelen, line);
#endif
#ifdef DISPLAY_LINE_HEX
                  unsigned char *p;
                  //printf("Read %d:", linelen);
                  for (p = line; linelen-- > 0; p++)
                     //printf(" 0x%x", *p);
                  //printf("\n");
#endif
                  // Verify checksum
                  if (isCheckSumOk(line) == 0)
                  {
                     //printf("SUCCESS --> Checksum OK on line: \"%s\"\n", line);
                     processLine(line);
                  }
               }
            }

            else if (pos == sizeof(line) - 1)
            {
               // Close string
               line[pos] = 0;
               linelen = pos;
               pos = 0;

               printf("ERROR: no new line read in line: \"%s\"\n", line);
            }

            else if (pos == sizeof(buf) - 1)
            {
               // Close string
               line[pos] = 0;
               linelen = pos;
               pos = 0;

               printf("ERROR: no new line read in buffer: \"%s\"\n", buf);
            }

            else
            {
               pos++;
            }

            i++;
         }

#ifdef DISPLAY_BUFFER_STRING
            buf[rdlen] = 0;
            printf("Read %d: \"%s\"\n", rdlen, buf);
#endif
#ifdef DISPLAY_BUFFER_HEX
            unsigned char *p;
            printf("Read %d:", rdlen);
            for (p = buf; rdlen-- > 0; p++)
                printf(" 0x%x", *p);
            printf("\n");
#endif
        }
        else if (rdlen < 0)
        {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        }


      /* Check if it's time to send a message to Domoticz */
      if (send_message)
      {
         send_message = 0;

         //Calculate values to send
         //int SINST = (int)(teleinfo.SINSTS) - (int)(teleinfo.SINSTI);
                        int SINST =  (int)(teleinfo.SINSTI);
         char SINST_str[12]; sprintf(SINST_str, "%d", SINST);

         //int EAT = (int)(teleinfo.EAST) - (int)(teleinfo.EAIT);
                        int EAT =  (int)(teleinfo.EAIT);
         char EAT_str[12]; sprintf(EAT_str, "%d", EAT);

         //Construction of message to send
         char message [1000];
         strcpy(message, JSON_HEADER);
         strcat(message, SINST_str);
         strcat(message, ";");
         strcat(message, EAT_str);
         //Send message
         if(sendUrl(message) == 0)
         {
            printf("DEBUG --> New message sent: \"%s\"\n", message);
                                exit(0);
         }
      }
      else
      {
         gettimeofday(&tv2, &tz2);
         if((tv2.tv_sec - tv1.tv_sec) >= 10)
         {
            send_message = 1;
            tv1.tv_sec = tv2.tv_sec;
         }
      }

        /* sleep and repeat read */
        //sleep(1);
    } while (1);
}
Répondre