Skip to content
  • Blog
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Community Forum

  1. Home
  2. Categories
  3. Téléinfo
  4. MicroTéléinfo
  5. Lecture Linky via dongle et compteur via GPIO

Lecture Linky via dongle et compteur via GPIO

Scheduled Pinned Locked Moved MicroTéléinfo
35 Posts 3 Posters 9.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mikebzh44
    wrote on last edited by mikebzh44
    #26

    Ca commence à rentrer, merci pour les tuyaux 😉

    alt text

    Ce WE, je rajoute la lecture du Linky via ttyAMA0 et je fusionne mes 2 tabes (car j'avais une table pour les index du Linky et une table pour l'index du Sagem + ECS).

    Restera ensuite à intégrer les sondes de T° DHT11 et DS18B20 mais y a des nodes pour ça donc ça devrait le faire sans problème 😄

    Par contre, pour sauvegarder l'index du compteur Sagem dans le contexte, je fais flow.set('WH',value) mais pour lire la variable, je ne peux pas faire comme dans ton exemple (context.flow.WH) mais je dois passer par flow.get('WH')

    M 1 Reply Last reply
    • M mikebzh44

      Ca commence à rentrer, merci pour les tuyaux 😉

      alt text

      Ce WE, je rajoute la lecture du Linky via ttyAMA0 et je fusionne mes 2 tabes (car j'avais une table pour les index du Linky et une table pour l'index du Sagem + ECS).

      Restera ensuite à intégrer les sondes de T° DHT11 et DS18B20 mais y a des nodes pour ça donc ça devrait le faire sans problème 😄

      Par contre, pour sauvegarder l'index du compteur Sagem dans le contexte, je fais flow.set('WH',value) mais pour lire la variable, je ne peux pas faire comme dans ton exemple (context.flow.WH) mais je dois passer par flow.get('WH')

      M Offline
      M Offline
      mikebzh44
      wrote on last edited by mikebzh44
      #27

      La lecture de /dev/ttyAMA0 marche bien debug :

      
      ADSC	061961603260	5
      VTIC	02	J
      DATE	E210424091645		D
      NGTF	H PLEINE/CREUSE 	\
      LTARF	 HEURE  PLEINE  	A
      EAST	010893318	0
      EASF01	005110053	1
      EASF02	005783265	G
      EASF03	000000000	$
      EASF04	000000000	%
      EASF05	000000000	&
      EASF06	000000000	'
      EASF07	000000000	(
      EASF08	000000000	)
      EASF09	000000000	*
      EASF10	000000000	"
      EASD01	005110053	/
      EASD02	005783265	E
      EASD03	000000000	"
      EASD04	000000000	#
      EAIT	000038838	#
      ERQ1	000007904	O
      ERQ2	000007294	R
      ERQ3	000040821	L
      ERQ4	004086122	U
      IRMS1	002	0
      URMS1	234	C
      PREF	09	H
      PCOUP	09	"
      SINSTS	00465	U
      SMAXSN	E210424063606	01899	G
      SMAXSN-1	E210423060619	02700	S
      SINSTI	00000	<
      SMAXIN	E210424000000	00000	M
      SMAXIN-1	E210423134052	00634	F
      CCASN	E210424090000	00460	8
      CCASN-1	E210424083000	00836	_
      CCAIN	E210424090000	00000	$
      CCAIN-1	E210424083000	00000	D
      UMOY1	E210424091000	234	+
      STGE	001A4501	A
      MSG1	PAS DE          MESSAGE         	<
      PRM	14275687320408	:
      RELAIS	000	B
      NTARF	02	O
      NJOURF	00	&
      NJOURF+1	00	B
      PJOURF+1	0000C001 ...
      

      Mais quand je branche ma fonction de décodage :

      // Enlever les codes début et fin de trame
      var lines = msg.payload.toString().replace("\u0002\n","").replace("\r\u0003","");
      
      // Récupérer chaque ligne une à une
      lines = lines.split("\r\n");
      for (var line in lines) 
      {
      	var i;
        	var checksum = 32;
        	
        	// Recupérer le label, la valeur et la checksum
        	// si la checksum est un espace on le remplace par un caractère non 
        	// autorisé en checksum (ici 's') pour eviter pb de split
        	// donc espace espace devient espace s
      	var myline = lines[line].toString().replace("  "," s").split(" ");
      	
      	// on dépile nos 3 valeurs
      	var check = myline.pop();
      	var value = myline.pop();
      	var label = myline.pop();
      	
      	// On peu repositionner la checksum à espace si c'était le cas
      	if (check == "s") check = " ";
      
      	// Calcul de la checksum sur ce qu'on a reçu, on balaye tous les caractères		
        	for (i = 0; i < label.length; i++) checksum += label.charCodeAt(i);
        	for (i = 0; i < value.length; i++) checksum += value.charCodeAt(i);
       	checksum = ((checksum%256) & 63) + 32;
       	checksum = String.fromCharCode(checksum);
      	
      	// Checksum correcte ?
       	if (checksum == check )
       	{
      	    if ( label == "EASF01")
      	    {
      	        flow.set("HC",parseInt(value,10));
      	    }
      	    if ( label == "EASF02")
      	    {
      	        flow.set("HP",parseInt(value,10));
      	    }
      	    if ( label == "LTARF")
      	    {
      	        if (value == 'HEURE  PLEINE')
      	        {
      	            flow.set("TARIF",'HP..');
      	        }
      	        else
      	        {
      	            flow.set("TARIF",'HC..');
      	        }
      	    }
      	    if ( label == "IRMS1")
      	    {
      	        flow.set(label,parseInt(value,10));
      	    }
      	    if ( label == "SINSTS")
      	    {
      	        flow.set(label,parseInt(value,10));
      	    }
      	    if ( label == "EAIT")
      	    {
      	        flow.set(label,parseInt(value,10));
      	    }
      	}
      	else
      	{
      		console.log("'%s' '%s' '%s' => Bad Checksum '%s'", label, value, check, checksum );
      	}
      }
      
      

      J'ai un message d'erreur dans le debug :

      TypeError: Cannot read property 'length' of undefined

      Le parsing est différent entre les trames Historiques et Standard ?

      Car j'ai pris le code dans ton exemple sur une trame Historique :

      http://hallard.me/pitinfo/

      Si ça peut aider, voici les trames reçues avec picocom :

      Trames_Linky.txt

      M 1 Reply Last reply
      • M mikebzh44

        La lecture de /dev/ttyAMA0 marche bien debug :

        
        ADSC	061961603260	5
        VTIC	02	J
        DATE	E210424091645		D
        NGTF	H PLEINE/CREUSE 	\
        LTARF	 HEURE  PLEINE  	A
        EAST	010893318	0
        EASF01	005110053	1
        EASF02	005783265	G
        EASF03	000000000	$
        EASF04	000000000	%
        EASF05	000000000	&
        EASF06	000000000	'
        EASF07	000000000	(
        EASF08	000000000	)
        EASF09	000000000	*
        EASF10	000000000	"
        EASD01	005110053	/
        EASD02	005783265	E
        EASD03	000000000	"
        EASD04	000000000	#
        EAIT	000038838	#
        ERQ1	000007904	O
        ERQ2	000007294	R
        ERQ3	000040821	L
        ERQ4	004086122	U
        IRMS1	002	0
        URMS1	234	C
        PREF	09	H
        PCOUP	09	"
        SINSTS	00465	U
        SMAXSN	E210424063606	01899	G
        SMAXSN-1	E210423060619	02700	S
        SINSTI	00000	<
        SMAXIN	E210424000000	00000	M
        SMAXIN-1	E210423134052	00634	F
        CCASN	E210424090000	00460	8
        CCASN-1	E210424083000	00836	_
        CCAIN	E210424090000	00000	$
        CCAIN-1	E210424083000	00000	D
        UMOY1	E210424091000	234	+
        STGE	001A4501	A
        MSG1	PAS DE          MESSAGE         	<
        PRM	14275687320408	:
        RELAIS	000	B
        NTARF	02	O
        NJOURF	00	&
        NJOURF+1	00	B
        PJOURF+1	0000C001 ...
        

        Mais quand je branche ma fonction de décodage :

        // Enlever les codes début et fin de trame
        var lines = msg.payload.toString().replace("\u0002\n","").replace("\r\u0003","");
        
        // Récupérer chaque ligne une à une
        lines = lines.split("\r\n");
        for (var line in lines) 
        {
        	var i;
          	var checksum = 32;
          	
          	// Recupérer le label, la valeur et la checksum
          	// si la checksum est un espace on le remplace par un caractère non 
          	// autorisé en checksum (ici 's') pour eviter pb de split
          	// donc espace espace devient espace s
        	var myline = lines[line].toString().replace("  "," s").split(" ");
        	
        	// on dépile nos 3 valeurs
        	var check = myline.pop();
        	var value = myline.pop();
        	var label = myline.pop();
        	
        	// On peu repositionner la checksum à espace si c'était le cas
        	if (check == "s") check = " ";
        
        	// Calcul de la checksum sur ce qu'on a reçu, on balaye tous les caractères		
          	for (i = 0; i < label.length; i++) checksum += label.charCodeAt(i);
          	for (i = 0; i < value.length; i++) checksum += value.charCodeAt(i);
         	checksum = ((checksum%256) & 63) + 32;
         	checksum = String.fromCharCode(checksum);
        	
        	// Checksum correcte ?
         	if (checksum == check )
         	{
        	    if ( label == "EASF01")
        	    {
        	        flow.set("HC",parseInt(value,10));
        	    }
        	    if ( label == "EASF02")
        	    {
        	        flow.set("HP",parseInt(value,10));
        	    }
        	    if ( label == "LTARF")
        	    {
        	        if (value == 'HEURE  PLEINE')
        	        {
        	            flow.set("TARIF",'HP..');
        	        }
        	        else
        	        {
        	            flow.set("TARIF",'HC..');
        	        }
        	    }
        	    if ( label == "IRMS1")
        	    {
        	        flow.set(label,parseInt(value,10));
        	    }
        	    if ( label == "SINSTS")
        	    {
        	        flow.set(label,parseInt(value,10));
        	    }
        	    if ( label == "EAIT")
        	    {
        	        flow.set(label,parseInt(value,10));
        	    }
        	}
        	else
        	{
        		console.log("'%s' '%s' '%s' => Bad Checksum '%s'", label, value, check, checksum );
        	}
        }
        
        

        J'ai un message d'erreur dans le debug :

        TypeError: Cannot read property 'length' of undefined

        Le parsing est différent entre les trames Historiques et Standard ?

        Car j'ai pris le code dans ton exemple sur une trame Historique :

        http://hallard.me/pitinfo/

        Si ça peut aider, voici les trames reçues avec picocom :

        Trames_Linky.txt

        M Offline
        M Offline
        mikebzh44
        wrote on last edited by
        #28

        En bidouillant un peu la lecture des trames (je vire le calcul des checksums entre autre), j'arrive à décoder les trames et extraire les couples label/values qui m'intéressent :

        // Enlever les codes début et fin de trame
        var lines = msg.payload.toString().replace("\u0002\n","").replace("\r\u0003","");
        
        // Récupérer chaque ligne une à une
        lines = lines.split("\r\n");
        
        for (var line in lines) 
        {
          	// Recupérer le label, la valeur et la checksum
          	// si la checksum est un espace on le remplace par un caractère non 
          	// autorisé en checksum (ici 's') pour eviter pb de split
          	// donc espace espace devient espace s
        	var myline = lines[line].toString().replace("  "," s").split(" ");
        	if (myline.length == 1)
        	{
                var entries = myline[0].split("\t");
                var label = entries[0];
                var value = entries[1];
        
                if ( label == "EASF01")
                {
                    flow.set("HC",parseInt(value,10));
                }
                if ( label == "EASF02")
                {
                    flow.set("HP",parseInt(value,10));
                }
                if ( label == "LTARF")
                {
                    if (value == 'HEURE  PLEINE')
                    {
                        flow.set("TARIF",'HP..');
                    }
                    else
                    {
                        flow.set("TARIF",'HC..');
                    }
                }
                if ( label == "IRMS1")
                {
                    flow.set(label,parseInt(value,10));
                }
                if ( label == "SINSTS")
                {
                    flow.set(label,parseInt(value,10));
                }
                if ( label == "EAIT")
                {
                    flow.set(label,parseInt(value,10));
                }
            }
        }
        
        
        CharlesC 1 Reply Last reply
        • M mikebzh44

          En bidouillant un peu la lecture des trames (je vire le calcul des checksums entre autre), j'arrive à décoder les trames et extraire les couples label/values qui m'intéressent :

          // Enlever les codes début et fin de trame
          var lines = msg.payload.toString().replace("\u0002\n","").replace("\r\u0003","");
          
          // Récupérer chaque ligne une à une
          lines = lines.split("\r\n");
          
          for (var line in lines) 
          {
            	// Recupérer le label, la valeur et la checksum
            	// si la checksum est un espace on le remplace par un caractère non 
            	// autorisé en checksum (ici 's') pour eviter pb de split
            	// donc espace espace devient espace s
          	var myline = lines[line].toString().replace("  "," s").split(" ");
          	if (myline.length == 1)
          	{
                  var entries = myline[0].split("\t");
                  var label = entries[0];
                  var value = entries[1];
          
                  if ( label == "EASF01")
                  {
                      flow.set("HC",parseInt(value,10));
                  }
                  if ( label == "EASF02")
                  {
                      flow.set("HP",parseInt(value,10));
                  }
                  if ( label == "LTARF")
                  {
                      if (value == 'HEURE  PLEINE')
                      {
                          flow.set("TARIF",'HP..');
                      }
                      else
                      {
                          flow.set("TARIF",'HC..');
                      }
                  }
                  if ( label == "IRMS1")
                  {
                      flow.set(label,parseInt(value,10));
                  }
                  if ( label == "SINSTS")
                  {
                      flow.set(label,parseInt(value,10));
                  }
                  if ( label == "EAIT")
                  {
                      flow.set(label,parseInt(value,10));
                  }
              }
          }
          
          
          CharlesC Offline
          CharlesC Offline
          Charles
          wrote on last edited by
          #29

          @mikebzh44 je te conseille vivement de garder les calculs de checksum histoire de ne pas te retrouver avec les valeurs aberrantes en database en cas de problème.

          M 1 Reply Last reply
          • CharlesC Charles

            @mikebzh44 je te conseille vivement de garder les calculs de checksum histoire de ne pas te retrouver avec les valeurs aberrantes en database en cas de problème.

            M Offline
            M Offline
            mikebzh44
            wrote on last edited by
            #30

            Oui, je vais revoir ma copie et réintégrer le calcul des checksum.

            Je les avais viré car j'avais des erreurs liées à la fonction length.

            Mais les trames Standard sont aussi différentes des Historique car les Historiques fournissent toujours un tuple (clé, valeur, check) alors que les Standards peuvent fournir un tuple (clé, timestamp, valeur, check) :

            SINSTS 00488 Z
            SMAXSN E210424063606 01899 G

            Voir carrément plus :

            PJOURF+1 0000C001 07248002 2324C001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE

            Autre question, pour utiliser /dev/ttyAMA0, on doit l'initialiser au boot du Pi, contrairement à ton dongle.

            Pour l'instant, j'ai mis la commande :

            stty -F /dev/ttyAMA0 1200 sane evenp parenb cs7 -crtscts

            dans la crontab de root avec @reboot

            Je suppose que c'est un peu crade comme manip, non ?

            CharlesC 1 Reply Last reply
            • M mikebzh44

              Oui, je vais revoir ma copie et réintégrer le calcul des checksum.

              Je les avais viré car j'avais des erreurs liées à la fonction length.

              Mais les trames Standard sont aussi différentes des Historique car les Historiques fournissent toujours un tuple (clé, valeur, check) alors que les Standards peuvent fournir un tuple (clé, timestamp, valeur, check) :

              SINSTS 00488 Z
              SMAXSN E210424063606 01899 G

              Voir carrément plus :

              PJOURF+1 0000C001 07248002 2324C001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE

              Autre question, pour utiliser /dev/ttyAMA0, on doit l'initialiser au boot du Pi, contrairement à ton dongle.

              Pour l'instant, j'ai mis la commande :

              stty -F /dev/ttyAMA0 1200 sane evenp parenb cs7 -crtscts

              dans la crontab de root avec @reboot

              Je suppose que c'est un peu crade comme manip, non ?

              CharlesC Offline
              CharlesC Offline
              Charles
              wrote on last edited by
              #31

              Autre question, pour utiliser /dev/ttyAMA0, on doit l'initialiser au boot du Pi, contrairement à ton dongle.

              c'est node red qui va la configurer la vitesse et le mode, à la condition tu actives la serial avec raspi-config

              cf : https://www.framboise314.fr/utiliser-le-port-serie-du-raspberry-pi-3-et-du-pi-zero/

              1 Reply Last reply
              • M mikebzh44

                Par contre, pour l'instant, je lis la sortie TIC du Linky via un programme Python qui utilise la bibliothèque PITinfo mais je dois bidouiller dans un script pour lancer le programme python en arrière plan puis au bout de 10s, je fais un grep et je kill le process car le programme python ne rend jamais la main.

                Pour le dongle, je pense utiliser ton programme :

                http://hallard.me/teleinfo-emoncms/

                Mais si je veux un programme qui sache lire le Linky et un autre qui sache lire le Sagem, il faut que je le compile 2 fois avec des options différentes (pour qu'ils se nomment différemment, pour qu'ils aient des fichiers de conf différents, ...) ? Va falloir que je me plonge de le makefile et le fichier .c, ça va me rappeler ma jeunesse 😄

                Marc DuboisM Offline
                Marc DuboisM Offline
                Marc Dubois
                wrote on last edited by
                #32

                @mikebzh44 J'ai exactement le meme problème avec mon pi zero, on dirait que le pi zero n'est pas assez puissant pour rattraper le retard stocker dans le buffer du serial. Meme pas sur que sa sois ca, mais ce c'est chiant ducoup on peux pas mettre un simple cron pour start le programme python.

                En attendant de trouver une vrai solution je suis obliger de viderr le buffer du serial avec picocom une ou deux fois car par moment il crash aussi, et ensuite je peux demmarer mon programme python dans un screen ducoup. Ces pas propre mais j'ai pas reussi a automatiser ca sur un cron encore c'est trop instable et c'est jamais le meme comportement.

                CharlesC 1 Reply Last reply
                • Marc DuboisM Marc Dubois

                  @mikebzh44 J'ai exactement le meme problème avec mon pi zero, on dirait que le pi zero n'est pas assez puissant pour rattraper le retard stocker dans le buffer du serial. Meme pas sur que sa sois ca, mais ce c'est chiant ducoup on peux pas mettre un simple cron pour start le programme python.

                  En attendant de trouver une vrai solution je suis obliger de viderr le buffer du serial avec picocom une ou deux fois car par moment il crash aussi, et ensuite je peux demmarer mon programme python dans un screen ducoup. Ces pas propre mais j'ai pas reussi a automatiser ca sur un cron encore c'est trop instable et c'est jamais le meme comportement.

                  CharlesC Offline
                  CharlesC Offline
                  Charles
                  wrote on last edited by
                  #33

                  @Marc-Dubois Attention à bien désactiver la soft uart (mais on perd le bluetooth), une fois désactivée le PI est largement capable de digérer les trames séries à 9600bauds.

                  Lire ici et la

                  En gros bien mettre ces lignes dans le /boot/config.txt

                  dtoverlay=pi3-disable-bt
                  dtoverlay=pi3-miniuart-bt
                  
                  Marc DuboisM 1 Reply Last reply
                  • CharlesC Charles

                    @Marc-Dubois Attention à bien désactiver la soft uart (mais on perd le bluetooth), une fois désactivée le PI est largement capable de digérer les trames séries à 9600bauds.

                    Lire ici et la

                    En gros bien mettre ces lignes dans le /boot/config.txt

                    dtoverlay=pi3-disable-bt
                    dtoverlay=pi3-miniuart-bt
                    
                    Marc DuboisM Offline
                    Marc DuboisM Offline
                    Marc Dubois
                    wrote on last edited by
                    #34

                    @Charles J'ai test ces parametre, resultat mon Pi zero boot plus!
                    Au moins ca me fait l'occasion de passer sur le pi3b, quel merde ce pi zero on peux rien faire avec

                    CharlesC 1 Reply Last reply
                    • Marc DuboisM Marc Dubois

                      @Charles J'ai test ces parametre, resultat mon Pi zero boot plus!
                      Au moins ca me fait l'occasion de passer sur le pi3b, quel merde ce pi zero on peux rien faire avec

                      CharlesC Offline
                      CharlesC Offline
                      Charles
                      wrote on last edited by
                      #35

                      @Marc-Dubois Pourtant j'ai 4 Pi Zero, je n'ai aucun soucis avec (peut être pas la dernière version de l'OS ceci dit)

                      1 Reply Last reply

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      3

                      Online

                      5.8k

                      Users

                      565

                      Topics

                      5.3k

                      Posts

                      Top Topics

                      Popular Tags

                      teleinfo
                      25 topics
                      arduino
                      19 topics
                      remora
                      16 topics
                      esp8266
                      10 topics
                      arduipi
                      10 topics
                      raspberry
                      8 topics
                      wifinfo
                      7 topics
                      broadcast
                      7 topics
                      Copyright © 2022 Charles-Henri Hallard | Return to blog page | Powered by NodeBB
                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Blog
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups