Lecture Linky via dongle et compteur via GPIO
-
@mikebzh44 ouais j'suis pas fan des limit je m'en sers uniquement quand ca va très vite et que je veux limiter.
T'as essayer de faire un limit 1msg/59s pour voir ?
Sinon moi je stocke les valeurs de chaque trame dans le contexte (espèce de variable globale node Red) puis je mets des inject node (mode trigger) qui viennent récupérer les valeurs du contexte
Un toutes les 10s pour les valeurs temps réel et un autre tt les 5 min pour toutes les valeurs (inutile de charger la BDD pour les index par exemple) ce qui donne un truc comme ça
je te mets le flow (t'as juste à l'importer dans node red) pour que tu puisses trouver des idées
[{"id":"21d0dbd3.42c4f4","type":"function","z":"8b43a51b.e87958","name":"Valeurs Temps Réel","func":"var str = \"\";\nvar ti = context.global.teleinfo;\n\nfor (var label in ti)\n{\n\tif (label==\"ADPS\" || label==\"PAPP\" || label==\"TENSION\" || label==\"IINST1\" || label==\"IMAX1\" )\n\t{\n if (str.length>0)\n str+=\",\";\n \n str += label + \":\"+ ti[label];\n\t} \n\n\tif ( label==\"PAPP\" )\n\t{\n if (str.length>0)\n str+=\",\";\n\n str += label + \"_\" + ti[\"PTEC\"] +\":\"+ ti[label];\n\t}\n\n}\n\nreturn [ { payload: str } ];\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":350,"y":180,"wires":[[]]}]
-
Cool, merci pour le tuyau, je teste ça ce soir.
Et avec ce fameux contexte, je peux avoir un flow qui va lire la sortie TIC de mon Sagem via /dev/ttyUSB0, un 2éme qui va lire celle du Linky via /dev/ttyAMA0 et un 3ème qui va récupérer les données de mon sous-compteur d'injection du surplus dans mon chauffe via une requête HTTP (c'est un Wemos sous EspEasy qui est branché à la sortie RS485 du sous-compteur) puis agréger toutes ces informations pour ne faire qu'un seul ordre INSERT dans ma BDD ?
Je suppose qu'il faut que mon flow Linky stocke les données qui m'intéressent dans context.global.Linky (par exemple), de même pour context.global.Sagem et context.global.ECS et toutes les 1m, j'ai une fonction qui récupères les valeurs de ces 3 variables "globales" et je génère mon ordre INSERT, j'ai bon ?
Merci pour ton aide en tout cas, car cette programmation "graphique" est toute nouvelle pour moi
-
@mikebzh44 said in Lecture Linky via dongle et compteur via GPIO:
Cool, merci pour le tuyau, je teste ça ce soir.
Et avec ce fameux contexte, je peux avoir un flow qui va lire la sortie TIC de mon Sagem via /dev/ttyUSB0, un 2éme qui va lire celle du Linky via /dev/ttyAMA0 et un 3ème qui va récupérer les données de mon sous-compteur d'injection du surplus dans mon chauffe via une requête HTTP (c'est un Wemos sous EspEasy qui est branché à la sortie RS485 du sous-compteur) puis agréger toutes ces informations pour ne faire qu'un seul ordre INSERT dans ma BDD ?
Tout à fait
Je suppose qu'il faut que mon flow Linky stocke les données qui m'intéressent dans context.global.Linky (par exemple), de même pour context.global.Sagem et context.global.ECS et toutes les 1m, j'ai une fonction qui récupères les valeurs de ces 3 variables "globales" et je génère mon ordre INSERT, j'ai bon ?
C'est exactement ça
Merci pour ton aide en tout cas, car cette programmation "graphique" est toute nouvelle pour moi
c'est pratique et rapide hein ?
-
@charles Pratique, c'est certain ! Rapide, pas au début quand tu maîtrise que dalle
J'ai encore du mal à comprendre ces histoires de flow.
On met tous sur le même "graphe" ? On peut avoir plusieurs "graphes" qui peuvent être déployés ou non ?
Pour l'instant, tant que mon dongle n'est pas en production, je reste avec mes 2 RPi qui remplissent mes tables. Hier soir, j'ai donc dû arrêter le service Node Red pour ne pas qu'il continue à faire des INSERT alors que le dongle était débranché.
Mais si j'avais un autre flow (qui fait autre chose) et qui devait continuer à tourner, j'aurais dû faire comment pour désactiver uniquement la lecture TIC ?
Faut que je lise les tutos, ça doit bien être abordé
-
@mikebzh44 said in Lecture Linky via dongle et compteur via GPIO:
@charles Pratique, c'est certain ! Rapide, pas au début quand tu maîtrise que dalle
J'ai encore du mal à comprendre ces histoires de flow.
On met tous sur le même "graphe" ? On peut avoir plusieurs "graphes" qui peuvent être déployés ou non ?
oui tu peux créer des flow différents, tu as une option aussi pour désactiver un flow.
Pour l'instant, tant que mon dongle n'est pas en production, je reste avec mes 2 RPi qui remplissent mes tables. Hier soir, j'ai donc dû arrêter le service Node Red pour ne pas qu'il continue à faire des INSERT alors que le dongle était débranché.
Mais si j'avais un autre flow (qui fait autre chose) et qui devait continuer à tourner, j'aurais dû faire comment pour désactiver uniquement la lecture TIC ?
Perso je reste basique, moi je coupe les liens dans le flow (et tu déploie) exemple ton insert de bdd ou celui en sortie de la série.
Le vieil adage simpler is betterFaut que je lise les tutos, ça doit bien être abordé
-
Ca commence à rentrer, merci pour les tuyaux
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')
-
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 :
Si ça peut aider, voici les trames reçues avec picocom :
-
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)); } } }
-
@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.
-
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 GVoir 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 ?
-
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/
-
@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.
-
@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.
En gros bien mettre ces lignes dans le
/boot/config.txt
dtoverlay=pi3-disable-bt dtoverlay=pi3-miniuart-bt
-
@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 -
@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)