teleinfo linky mode standard

les autres capteurs : Sondes Météo, switches
bda
Messages : 15
Enregistré le : 21 févr. 2020, 15:33

Re: teleinfo linky mode standard

Message par bda »

Bonjour,

J'ai des panneaux photovoltaïques dont la production est en vente totale et on vient de m'installer 2 compteurs Linky (Sagem) qui remplacent 3 compteurs de la génération précédente. J'utilise un module PiTinfo branché sur un RPi3 pour envoyer les données à Domoticz. Avec le nouveau compteur Linky de consommation, tout fonctionne à nouveau correctement mais avec le compteur de production, je n'ai aucune donnée. J'ai essayé à 1200 bauds (mode historique) ou à 9600 bauds (mode standard). D'où ces questions:
  • comment peut-on savoir dans quel mode on se trouve ?
  • est-il possible qu'il n'y ait aucune donnée sur la sortie Teleinfo (L1 L2)
Merci pour aide.

bda
Messages : 15
Enregistré le : 21 févr. 2020, 15:33

Re: teleinfo linky mode standard

Message par bda »

Bon, après un peu de recherche, je me réponds à moi même: le compteur est bien en mode standard et j'arrive à lire les données avec le circuit décrit à: https://blog.bigd.fr/suivre-sa-consomma ... rique-edf/

bda
Messages : 15
Enregistré le : 21 févr. 2020, 15:33

Re: teleinfo linky mode standard

Message par bda »

J'ajoute que ce circuit marche aussi avec un ESP8266 (NodeMCU). J'ai mis une résistance de 270 Ohm en série à l'entrée du photocoupleur et 2,7 kOhm en pullup avec le 3,3V fournit le NodeMCU.

bda
Messages : 15
Enregistré le : 21 févr. 2020, 15:33

Re: teleinfo linky mode standard

Message par bda »

Bonjour,
Quelques précisions concernant l'indication de puissance produite dans le cas d'un Linky en mode standard. Quand la production est active (le jour) l'étiquette SINSTI donne bien la puissance produite avec une valeur cohérente avec celle donnée par l'onduleur et aussi avec l'énergie injectée (étiquette EAIT).
Quand la production est inactive (la nuit) SINSTI au lieu d'indiquer 0 donne en permanence une valeur comprise entre 32 et 34W. L'étiquette SINSTS, elle, donne une valeur de 0 quand il y a production et une valeur comprise entre 32 et 34W quand il n'y a pas de production. À de rares exceptions près (pb d'arrondi ?) la modulation entre 32 et 34 W est la même pour les 2 indicateurs. J'en déduit que pour avoir la bonne valeur de la puissance injectée, il faut prendre SINSTI - SINSTS. En ramenant à 0 les valeurs proches de 0 si on veut pinailler.

Carthman
Messages : 69
Enregistré le : 22 sept. 2016, 16:27

Re: teleinfo linky mode standard

Message par Carthman »

Bonjour,

Je galères un peu à faire fonctionner mon module Teleinfo USB avec le Linky en mode standard, mais si je comprends bien c'est pas pris en charge par Domoticz, donc il faut passer par un script ou plugin "Maison" , genre celui de Binuit ?
Modifié en dernier par Carthman le 05 oct. 2020, 09:31, modifié 1 fois.

higgins91
Messages : 491
Enregistré le : 17 nov. 2016, 11:06

Re: teleinfo linky mode standard

Message par higgins91 »

c'est quoi ton module téléinfo ?
Je suis passé au linky depuis quelques semaines et le seul problème rencontré c'est que j'avais changé le baudrate du port série vers 9600, alors que fallait le laisser à 1200... J'utilise le stick usb "µtéléinfo" (http://hallard.me/utinfo/)

Carthman
Messages : 69
Enregistré le : 22 sept. 2016, 16:27

Re: teleinfo linky mode standard

Message par Carthman »

C'est le module USB de Cartelectronic, mais le problème c'est pas le passage au Linky, c'est le passage au mode Standard.
Toi tu dois encore être en Mode Historique !

Je n'avais aucun problème avant avec le Linky en mode historique !

Et bien sûr avec la vitesse à 1200, en faisant cat /dev/ttyUSB12 je ne vois rien passer !

Carthman
Messages : 69
Enregistré le : 22 sept. 2016, 16:27

Re: teleinfo linky mode standard

Message par Carthman »

Binuit a écrit : 17 févr. 2018, 11:56 Manip détaillée (pour une Raspberry avec Domoticz installé et un module TIC-->USB qui relie la TIC au Raspberry): [/u]
1) Dans Domoticz, créer un nouveau matériel - Type : Dummy (does nothing, use for virtual switches only)
2) Dans ce nouveau matériel, appuyer sur le bouton "Créer capteurs virtuels" et sélectionner le type souhaité (par exemple "Electrique : Instantané+Compteur")
3) Voilà, un nouveau device a été créé, son IDX est visible dans l'onglet "Dispositifs"
4) Maintenant il n'y a plus qu'à alimenter ce device avec des données, c'est ce que va faire notre driver teleinfo : driver_teleinfo.c.zip
5) Modifier le fichier en indiquant la configuration souhaitée
6) Compiler le fichier (requiert que curl soit installé) : sudo cc driver_teleinfo.c -lcurl
7) voilà vous n'avez plus qu'à lancer le binaire généré : ./a.out
--> Normalement vous devriez voir des lignes de debug s'afficher dans le terminal avec les lignes lues par le driver. Et toutes les 10 secondes, le driver envoie la puissance instantanée à un device de Domoticz.
Bonsoir,

Est-ce que quelqu'un serait susceptible de partager le code de ce "Driver", car il n'est plus possible de le télécharger ?

Merci !

Martial
Messages : 128
Enregistré le : 03 mars 2017, 18:58

Re: teleinfo linky mode standard

Message par Martial »

Bonjour Carthman,
Toujours en recherche du code?
Voici celui que j'utilise (fait à partir de celui que tu recherches).
Il faut lui passer, en arguments, l'url à appeler pour mettre à jour domoticz, avec les idx des 3 widgets.
Exemple: /home/pi/teleinfo/teleinfo http://192.168.1.23:8080/json.htm 794 795 799

Code : Tout sélectionner

#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>
// On va passer en parametres:
// - l'url json du serveur Domoticz
// - l'idx Domoticz du smartmeter
// - l'idx          du suivi courant tri-phasé (de type Current,CM113 Electrisave)
// - l'idx          du switch HC/HP

//--------------------------------------------------
// 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/ttyUSBTINFO";
const speed_t BAUD_RATE = B9600;
const char DEMILITER = 0x09;

//const char* JSON_HEADER = "http://192.168.1.23:8080/json.htm?type=command&param=udevice&idx=804&nvalue=0&svalue=";
char JSON_HEADER[1024]; // = "http://192.168.1.23:8080/json.htm?type=command&param=udevice&idx=804&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;
        unsigned int EASF01;
        unsigned int EASF02;
                unsigned int IRMS1;
                unsigned int IRMS2;
                unsigned int IRMS3;
                unsigned int TARIF;
} Teleinfo;

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

Teleinfo teleinfo = { .EAST = 0, .EAIT = 0, .SINSTS = 0, .SINSTI = 0, .EASF01 = 0, .EASF02 = 0, .IRMS1 = 0, .IRMS2 = 0, .IRMS3 = 0, .TARIF = 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;
        }
        if(strcmp(label, "IRMS1") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.IRMS1 = (unsigned int)val;
                else return -1;
        } else
        if(strcmp(label, "IRMS2") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.IRMS2 = (unsigned int)val;
                else return -1;
        } else
        if(strcmp(label, "IRMS3") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.IRMS3 = (unsigned int)val;
                else return -1;
        } else
        if(strcmp(label, "NTARF") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.TARIF = (unsigned int)val;
                else return -1;
        } else
        if(strcmp(label, "EASF01") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.EASF01 = (unsigned int)val;
                else return -1;
        } else
        if(strcmp(label, "EASF02") == 0) {
                val = strToUL(elem1);
                if (val != -1) teleinfo.EASF02 = (unsigned int)val;
                else return -1;
        }

}

int main(int argc, char * argv[])
{
    //freopen("out.txt", "a", stdout);
    int fd;
    int wlen;
        int i;
    unsigned char line[MAX_LINE_SIZE];
    unsigned int linelen = 0;
    unsigned int pos = 0;
        if(argc < 4)
        {
                printf("Usage: url json du domoticz à alimenter\r\n");
        printf("       idx du smartmeter\r\n");
                printf("       idx du suivi courant tri-phasé\r\n");
                printf("       idx du switch HC/HP");
                exit(0);
        }
        for(i = 0 ; i< argc ; i ++)
        {
                printf("   argv[%d] : ‘%s’ \n", i, argv[i]);
        }
        sprintf(JSON_HEADER,"%s", argv[1]);

    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);

                        int EASF01 =  (int)(teleinfo.EASF01);
                        char EASF01_str[12]; sprintf(EASF01_str, "%d", EASF01);

                        int EASF02 =  (int)(teleinfo.EASF02);
                        char EASF02_str[12]; sprintf(EASF02_str, "%d", EASF02);

                                                int IRMS1 =  (int)(teleinfo.IRMS1);
                        char IRMS1_str[12]; sprintf(IRMS1_str, "%d", IRMS1);

                                                int IRMS2 =  (int)(teleinfo.IRMS2);
                        char IRMS2_str[12]; sprintf(IRMS2_str, "%d", IRMS2);

                                                int IRMS3 =  (int)(teleinfo.IRMS3);
                        char IRMS3_str[12]; sprintf(IRMS3_str, "%d", IRMS3);

                                                int TARIF =  (int)(teleinfo.TARIF);
                        char TARIF_str[12]; sprintf(TARIF_str, "%d", TARIF);
                        //Construction of messages to send
                                                //On commence par le smartmeter
                        char message [1000];
                        strcpy(message, JSON_HEADER);
                                                strcat(message, "?type=command&param=udevice&idx=");
                                                strcat(message, argv[2]);
                                                strcat(message, "&nvalue=0&svalue=");
                                                strcat(message, EASF02_str);
                        strcat(message, ";");
                        strcat(message, EASF01_str);
                        strcat(message, ";0;0;");
                        strcat(message, SINST_str);
                        strcat(message, ";0");
                        //Send message
                        if(sendUrl(message) == 0)
                        {
                                printf("DEBUG --> New message sent: \"%s\"\n", message);
                        }
                                                //Puis le CM113, courant triphasé
                                                strcpy(message, JSON_HEADER);
                                                strcat(message, "?type=command&param=udevice&idx=");
                                                strcat(message, argv[3]);
                                                strcat(message, "&nvalue=0&svalue=");
                                                strcat(message, IRMS1_str);
                        strcat(message, ";");
                        strcat(message, IRMS2_str);
                        strcat(message, ";");
                        strcat(message, IRMS3_str);
                        strcat(message, ";");
                        //Send message
                        if(sendUrl(message) == 0)
                        {
                                printf("DEBUG --> New message sent: \"%s\"\n", message);
                        }
                                                //Puis le tarif en cours 1= HC 2= HP
                                                if (teleinfo.TARIF == 1)
                                                {
                                                        sprintf(message, "%s?type=command&param=udevice&idx=%s&nvalue=1&svalue=(1)+Heures+Creuses",
                                                        JSON_HEADER, argv[4]);
                                                }
                        if (teleinfo.TARIF == 2)
                                                {
                                                        sprintf(message, "%s?type=command&param=udevice&idx=%s&nvalue=1&svalue=(2)+Heures+Pleines",
                                                        JSON_HEADER, argv[4]);
                                                }
                        //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);
}
EDIT: Tu as le code original en page 2 de ce thread

Carthman
Messages : 69
Enregistré le : 22 sept. 2016, 16:27

Re: teleinfo linky mode standard

Message par Carthman »

Bonjour Martial,

Merci pour ton retour.
Oui je suis toujours en recherche du code, merci de me l'avoir transmis.
Je ne m'étais pas occupé de ça depuis un moment, mais je m'y remets un peu car je n'ai plus de suivi de conso, qui me servait entre autre à faire du délestage, et là avec l'hiver qui s'installe et la conso électrique qui s'envole, j'aimerais éviter que mon Linky se coupe !

Alors je vais essayer de bidouiller un peu avec ce code, mais j'ai quand même quelques questions, car je ne suis pas très familier avec ces lignes.

- Est-ce un script à inscrire dans la crontab ?
- Je n'ai pas besoin des mêmes paramètres que toi car je suis producteur en tarif BASE, donc j'aurais besoin de EAST et EAIT pour les compteurs kwh et SINSTS et SINSTI pour les puissances instantanées.
Comment faire pour adpater le code à mes besoins ?

Merci !

Répondre