10

PiTInfo : Téléinfo, Emoncms avec Node Red sur Raspberry PI, moins de 30 min, moins de 10€

Après le Dongle téléinfo le plus petit, j’ai eu pas mal de demandes de personnes souhaitant pouvoir réaliser de manière simple l’intégration de la téléinformation sur Raspberry PI avec un montage. Voilà qui est fait. De plus, j’en ai profité pour changer d’optique et simplifier les choses au niveau logiciel et gestion de l’information.

Edit du 13/10/2015La nouvelle version de PITinfo V1.2 possède maintenant la modification basée sur un transistor FET. Voir le nouvel article dédié ici.

Bien que cette carte fonctionne parfaitement avec le programme que j’ai réalisé qui envoi les trames sur le réseau ainsi que vers une base mysql et emoncms, il faut néanmoins le compiler avec les dépendances nécessaires et faire un fichier de configuration correct, puissant mais pas si simple de prime abord.

J’ai donc choisi de faire exactement la même chose avec Node Red, et vous allez voir que c’est ultra simple, super rapide, très visuel et surtout extensible à l’infini. Oui, ok, je kiffe node red, mais vous aussi à la fin de cet article, du moins je l’espère.

Bon, reprenons… mais pour commencer voici le montage final avec la carte enfichée sur le Pi

PiTinfo montée sur Raspberry PI

PiTinfo montée sur Raspberry PI

La carte électronique

J’ai utilisé le montage le plus classique du net et très éprouvé par la carte ArduiPi et réalisé un PCB afin de faire propre. J’ai choisi volontairement des composants classiques afin qu’ils soient soudables même par des débutants.

Schéma de fonctionnement

Schéma de fonctionnement

Les composants nécessaires :

PiTInfo matériel nécessaire

PiTInfo matériel nécessaire

J’ai commandé les PCB chez mon fournisseur habituel pour les prototypes, vous pouvez en commander chez OSHPark pour $3.20 les 3, frais de port compris. Voici le lien direct pour les commander.

Au minimum, vous avez 2 composants à souder, l’optocoupleur et une résistance (R3). Comme prévu la résistance R1 n’est pas nécessaire sur un Raspberry PI et peut être omise. Optionnellement j’ai ajouté une LED au format 3mm ou CMS et sa résistance associée R2. Ceci afin de la faire clignoter à réception de trame valide de téléinfo, mais c’est plus ludique et visuel que fonctionnel, ce n’est absolument pas obligatoire.

Aujourd’hui, je viens de monter les composants, et voici les 3 cartes montées, dont une avec une LED cms. Le connecteur téléinfo (les 2 fils qui viennent du compteur) est soudé dessous (pas obligatoire) afin de ne pas être ennuyé si votre Pi est dans un boitier. J’ai aussi “écarté” les trous du connecteur s’enfichant sur le Pi, ainsi, pour faire des tests, pas besoin de le souder, ça tient tout seul grâce à cette astuce.

PiTinfo, Connecteur Téléinfo dessous et LED cms

PiTinfo, Connecteur Téléinfo dessous et LED cms

PiTInfo 3 cartes montées

PiTInfo 3 cartes montées

 

Configuration du Raspberry PI

Se connecter sur le Pi en ssh puis commencer par un update en exécutant les commandes suivantes:

sudo apt-get update
sudo apt-get upgrade

Installation des packages nécessaires, picocom est un terminal série permettant de vérifier que les informations de la téléinfo arrivent bien. screen est un outil génial quand on souhaite lancer des processus en arrière plan et pouvoir consulter à posteriori les affichage (stdout). Le temps d’écrire cet article et j’ai découvert le management de node red (startup) via pm2, donc picocom et screen ne sont pas nécessaires. Ceci dit, il font partie d’une toolbox de base à mon sens donc je les installe.

sudo apt-get install picocom screen

Installation des modules de développement

sudo apt-get install -y build-essential python-dev python-rpi.gpio libicu-dev

Désactiver le terminal via la liaison série (car elle va être utilisée par la téléinfo)

sudo raspi-config

Aller dans le menu “Advanced Options”, sélectionner “‘Serial” et à la question ” Would you like a login shell to be accessible over serial? ” sélectionner No puis Ok et enfin Finish. Il est possible que vous deviez rebooter le Pi après cela.

Installation de nodejs

Rien de bien fancy, je suis allé chercher les informations sur le site de nodejs, les voici:

wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb

Pour ma part c’est un Pi avec 256M de RAM alors j’ai opté pour la dernière version 0.10.x de nodejs. J’ai remplacé dans les commandes précédentes

node_latest_armhf.deb

par

node_0.10.36_armhf.deb

c’est pour cela que les versions indiquées peuvent être différentes.

Vérification que node et npm sont ok:

pi@raspberrypi:~# node -v ; npm -v
v0.10.36
1.4.28
pi@raspberrypi:~#

Installation de Node Red

Installation de node-red et de quelques dépendances, notez que npm peut vous lancer plein de warning, aucun soucis ne vous inquiétez pas. La 1ère fois çà fait peur car c’est en couleur, mais c’est normal.

sudo npm install -g --unsafe-perm  node-red

Pour le démarrage de node red, nous allons utiliser pm2

sudo npm install -g pm2

Et enfin démarrer node red

pm2 start /usr/local/bin/node-red --node-args="--max-old-space-size=64" -- -v

Attention le Raspberry PI étant limité en RAM bien mettre le paramètre –max-old-space-size=128 (128Mo), pour ma part c’est un Pi 256Mo donc j’ai mis 64Mo

Pendant que j’y suis, pm2 est vraiment génial, il vous relance le process en cas de crash de celui-ci, pratique. De plus on peut aussi voir les infos qui sortent normalement vers la console avec le paramètre

logs

et des informations avec le paramètre

info

.

pi@raspberrypi ~ $ pm2 logs node-red
########### Starting streaming logs for [node-red] process
PM2: 2015-04-16 16:41:38: [PM2][WORKER] Started with refreshing interval: 30000
PM2: 2015-04-16 16:41:38: [[[[ PM2/God daemon launched ]]]]
PM2: 2015-04-16 16:41:38: BUS system [READY] on port /home/pi/.pm2/pub.sock
PM2: 2015-04-16 16:41:38: RPC interface [READY] on port /home/pi/.pm2/rpc.sock
PM2: 2015-04-16 16:41:39: Starting execution sequence in -fork mode- for app name:node-red id:0
PM2: 2015-04-16 16:41:39: App name:node-red id:0 online
node-red-0 (out): Welcome to Node-RED
node-red-0 (out): ===================
node-red-0 (out): 16 Apr 16:41:50 - [info] Node-RED version: v0.10.6
node-red-0 (out): 16 Apr 16:41:50 - [info] Node.js  version: v0.10.36
node-red-0 (out): 16 Apr 16:41:50 - [info] Loading palette nodes
node-red-0 (out): 16 Apr 16:42:09 - [info] Server now running at http://127.0.0.1:1880/
node-red-0 (out): 16 Apr 16:42:09 - [warn] ------------------------------------------
node-red-0 (out): 16 Apr 16:42:09 - [warn] [arduino] Error: Cannot find module 'arduino-firmata'
node-red-0 (out): 16 Apr 16:42:09 - [warn] [redisout] Error: Cannot find module 'redis'
node-red-0 (out): 16 Apr 16:42:09 - [warn] [mongodb] Error: Cannot find module 'mongodb'
node-red-0 (out): 16 Apr 16:42:09 - [warn] ------------------------------------------
node-red-0 (out): 16 Apr 16:42:09 - [info] User Directory : /home/pi/.node-red
node-red-0 (out): 16 Apr 16:42:09 - [info] Flows file     : /home/pi/.node-red/flows_raspberrypi.json
node-red-0 (out): 16 Apr 16:42:09 - [info] Creating new flows file
node-red-0 (out): 16 Apr 16:42:09 - [info] Starting flows
node-red-0 (out): 16 Apr 16:42:09 - [info] Started flows
^Cpi@raspberrypi ~ $ pm2 info node-red
Describing process with id 0 - name node-red
┌───────────────────┬─────────────────────────────────────────┐
│ status            │ online                                  │
│ name              │ node-red                                │
│ id                │ 0                                       │
│ path              │ /usr/local/bin/node-red                 │
│ args              │ -v                                      │
│ exec cwd          │ /home/pi                                │
│ error log path    │ /home/pi/.pm2/logs/node-red-error-0.log │
│ out log path      │ /home/pi/.pm2/logs/node-red-out-0.log   │
│ pid path          │ /home/pi/.pm2/pids/node-red-0.pid       │
│ mode              │ fork_mode                               │
│ node v8 arguments │ --max-old-space-size=64                 │
│ watch & reload    │ ✘                                       │
│ interpreter       │ node                                    │
│ restarts          │ 0                                       │
│ unstable restarts │ 0                                       │
│ uptime            │ 5m                                      │
│ created at        │ 2015-04-16T14:41:39.525Z                │
└───────────────────┴─────────────────────────────────────────┘
pi@raspberrypi ~ $

D’ailleurs on voit que node red n’as pas le module mongodb d’installé, on y remédie de suite en ajoutant aussi le module qui permet l’envoi vers emoncms

sudo npm install -g node-red-node-emoncms mongodb

Maintenant nous allons demander à pm2 de démarrer automatiquement node red au démarrage.

pi@raspberrypi ~ $ pm2 save
[PM2] Dumping processes
pi@raspberrypi ~ $ pm2 startup
[PM2] You have to run this command as root. Execute the following command:
      sudo env PATH=$PATH:/usr/local/bin pm2 startup linux -u pi
pi@raspberrypi ~ $ sudo env PATH=$PATH:/usr/local/bin pm2 startup linux -u pi
[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Generating system init script in /etc/init.d/pm2-init.sh
[PM2] Making script booting at startup...
[PM2] -linux- Using the command:
      su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
update-rc.d: using dependency based boot sequencing
[PM2] Done.
pi@raspberrypi ~ $

Ne pas oublier de d’exécuter la commande avec sudo lorsque demandé après avoir exécuté

pm2 startup

Allez, on reboote le Pi pour vérifier que tout est ok et nous en avons fini avec l’installation.

sudo reboot

Utilisation de node red

Maintenant que tout est prêt et que la carte PiTInfo est bien est bien enfichée dans le connecteur du Pi vous pouvez lancer l’interface de configuration de node red depuis votre navigateur préféré via http://adresseIPduPi:1880/ et vous devriez obtenir la page d’accueil suivante:

Accueil Node Red

Accueil Node Red

Maintenant je vais vous montrer comment simplement envoyer les données arrivant de la téléinfo vers emoncms. Pour utiliser l’interface de node red, il suffit du faire du drag & drop des modules sur le coté, et d’y mettre des liens. Tout est graphique.

Je ne vais pas entrer dans les détails du fonctionnement et du principe de Node Red, ce serait trop long, l’idée et de vous mettre le pied à l’étrier, et l’essayer, c’est l’adopter. Mais le principe est simple, c’est du traitement de flux, ça rentre, c’est traité et çà sort !

Vérifier que les données arrivent par la liaison série du Pi

Commençons par vérifier que les informations de la téléinfo arrivent sur la liaison série du Pi. On commence par prendre le module input serial et on le pose sur le dashboard. On double clique dessus pour modifier ses propriétés puis add new serial port et on clique sur le petit crayon. Il faut rentrer les informations suivantes :

  • Serial Port :
    /dev/ttyAMA0
  • Configuration : 1200 bps, 7 data bits, parité paire, 1 bit de stop (format de la téléinfo)
  • Split input

    0x3

     

    (le caractère fin de trame), comme çà la module suivant verra arriver une trame complète pour réaliser son traitement

Ce qui donne :

Node Red Serial Config

Node Red Serial Config

On va maintenant utiliser le debug pour vérifier que l’on reçoit bien les informations. Prendre l’output debug, le positionner sur le dashboard et le connecter avec le serial (click sur le carré, laisser appuyer et l’emmener sur l’autre carré). Ensuite cliquez sur Deploy (en haut à droite) et enfin choisissez l’onglet debug en haut à droite.

Node Red Debug Teleinfo

Node Red Debug Teleinfo

Vous devriez voir vos trames passer à droite. Notez qui si vous choisissiez l’onglet Info en ayant sélectionné un module sur le dashboard, vous aurez la documentation relative au module, un must très pratique !!!

Décodage des trames téléinfo

Pour cela il n’y a pas de module tout prêt, nous allons donc créer une fonction dédiée et y mettre le code javascript. Nous allons reformater la trame téléinfo dans un format compréhensible par un peu tout le monde, comme par exemple le module Emoncms de node red. Bien entendu la checksum de chaque étiquette du format de la téléinfo sera vérifiée.

Le format de sortie sera une chaîne de type Etiquette:valeur separées par des virgules.

Insérez un module fonction sur le dashboard et double cliquez dessus pour éditer son contenu, nommez le module par exemple formatage et y copier le code suivant :

// La trame complète est reçue dans 'msg'
var str = "";

// 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 )
 	{
		//console.log("'%s' '%s' '%s' => Checksum OK", label, value, check );

		// Correction des valeurs type string en numérique 		
		if (label == "OPTARIF")
    	{
      		// L'option tarifaire choisie (Groupe "OPTARIF") est codée sur 4 caractères alphanumériques 
      		// J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous 
      		// je mets le 4eme char à 0, trop de possibilités 
	      	value = value.substring(0, 3);
        
           	if      (value=="BAS") value=1;// BASE => Option Base. 
      		else if (value=="HC.") value=2;// HC.. => Option Heures Creuses. 
      		else if (value=="EJP") value=3;// EJP. => Option EJP. 
      		else if (value=="BBR") value=4;// BBRx => Option Tempo
      		else value = 0;
    	}
	    else if (label=="HHPHC")
	    {
	      // L'horaire heures pleines/heures creuses (Groupe "HHPHC") est codé par un caractère A à Y 
	      // J'ai choisi de prendre son code ASCII
	      value = value.charCodeAt();
	    }
	    else if ( label == "PTEC")
	    {
	      // La période tarifaire en cours (Groupe "PTEC"), est codée sur 4 caractères 
	      // J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous
	      if      (value=="TH..") value= 1; // Toutes les Heures. 
	      else if (value=="HC..") value= 2; // Heures Creuses. 
	      else if (value=="HP..") value= 3; // Heures Pleines. 
	      else if (value=="HN..") value= 4; // Heures Normales. 
	      else if (value=="PM..") value= 5; // Heures de Pointe Mobile. 
	      else if (value=="HCJB") value= 6; // Heures Creuses Jours Bleus. 
	      else if (value=="HCJW") value= 7; // Heures Creuses Jours Blancs (White). 
	      else if (value=="HCJR") value= 8; // Heures Creuses Jours Rouges. 
	      else if (value=="HPJB") value= 9; // Heures Pleines Jours Bleus. 
	      else if (value=="HPJW") value= 10;// Heures Pleines Jours Blancs (White). 
	      else if (value=="HPJR") value= 11;// Heures Pleines Jours Rouges. 
	      else value = 0;
	    }
	    
	    if ( label == "IINST") label = "IINST1"
	    if ( label == "IMAX") label = "IMAX1"
		
	
		//out.push({ payload: JSON.stringify(new function(){ this[label] = value;})});	
		//mymsg.push({ payload: new function(){ this[label] = value;} });	
		if (str.length>0) 
			str += "," ;	

		// Ajouter nouvelle étiquette plus valeur		
		str += label + ":" + value;	

	}
	else
	{
		console.log("'%s' '%s' '%s' => Bad Checksum '%s'", label, value, check, checksum );
	}
		
}
return [{ payload: str}];

Le traitement de certaines étiquettes spécifiques est fait pour les recoder comme le programme d’origine teleinfo afin de garder la compatibilité. Mais c’est aussi parce que Emoncms (enfin pas vraiment lui) ne sait pas traiter des chaines genre HP.. pour les heures pleines par exemple. Pas facile de grapher avec çà.

Voilà maintenant graphiquement, on relie l’entrée cette fonction à la sortie série et la sortie de cette fonction au debug et on déploie !

ce qui nous donne le flux suivant

Node Red Formatage Teleinfo

Node Red Formatage Teleinfo

Regardez l’onglet de debug, vous voyez, c’est maintenant une chaîne complète formatée. Parfait !!!

Et si maintenant on allumait la LED de la carte PiTInfo à chaque trame correctement reçue ?

Allumer la LED à chaque trame reçue

Rien de bien sorcier, on prend le module rpi-gpio (out) qu’on met sur le dashboard, on double clique dessus pour le configurer comme suit

Node Red Led Control

Node Red Led Control

GPIO Pin : 7 – GPIO7  Alors çà c’est agaçant il y a 3 manières d’énumérer les GPIO du Pi c’est jamais les mêmes, ici c’est la broche 7 du connecteur P1 et donc GPIO4 du contrôleur BCM mais la convention veut qu’on appelle çà GPIO7, je me fais avoir à chaque fois !!! Regardez la définition ici.

Bon, çà va contrôler la LED mais ce que je veux, c’est la faire clignoter. C’est à dire qu’elle s’allume à chaque trame reçue puis qu’elle s’éteigne au bout d’un certain temps par exemple 100ms. On prend dans les fonction le module trigger, on le pose sur le dashboard, et on l’édite comme suit :

Node Red Led Trigger

Node Red Led Trigger

Donc ce qui signifie : Si quelque chose arrive (et on connectera ce module à la sortie de formatage de la trame teleinfo) on positionne la sortie à 1 (ce qui allumera la LED si son module est connecté à la sortie de celui-ci) puis attendra 100ms et renverra un 0 sur sa sortie.

On refait les connexions et on déploie ce qui vous donnera çà :

Cerise sur le gâteau (non non, bien que ce soit sur fond blanc et que le carré dessous la LED ressemble à un pois vert, rien à voir avec la compagnie d’assurance), non seulement la LED clignote sur la carte PiTInfo, mais aussi dans le dashboard. Alors, toujours pas convaincu de la puissance et de la facilité de mise en oeuvre de Node Red ? Bien, alors continuons.

Envoyer les données vers emoncms

Facile, on prend le module Emoncms (facilement repérable, il est bleu), on le configure et on va le connecter à la sortie formatage.

Node Red emoncms config

Node Red emoncms config

Voilà rien de compliqué en soi. J’ai mis ma téléinfo sur le node 19 dans emoncms mais vous pouvez le laisser à vide, c’est juste que je fonctionne comme çà avec emoncms. N’oubliez pas de renseigner votre APIKey d’Emoncms.

Mais attention, encore une subtilité, emoncms limite le push des données à des intervalles de 5s, il faut donc veiller à respecter ce timing, pour ce faire Node Red y a déjà pensé, nous prenons un module existant nommé delay (à poser sur le dashboard) et à éditer comme ceci :

Node Red Teleinfo Delay

Node Red Teleinfo Delay

On limite la sortie à 6 message par minute soit un toutes les 10 secondes et on supprime les messages intermédiaires.

On connecte le tout et on déploie à nouveau, ce qui nous donne le workflow final suivant

Node Red Teleinfo Emoncms Workflow

Node Red Teleinfo Emoncms Workflow

Voilà, vous pouvez bien entendu renommer votre workspace (menu en haut à droite à coté du bouton deploy). Celui ci est automatiquement sauvé à chaque déploiement et automatiquement lancé au démarrage du Pi avec Node Red. Attention si jamais vous renommez votre Pi, pensez à renommer les fichiers flows correspondant dans

/home/pi/.node-red/

avec le nouveau nom.

Conclusion

Voilà, j’espère que cet article vous donnera des idées, comme par exemple envoyer les données dans une base de donnée ou autre mais surtout qu’il vous fera apprécier node red à sa juste valeur.

Je vous conseille d’y aller doucement sur les logs avec le Pi (les désactiver par exemple dans la config de pm2 car le module rpi.gpio de node red est très verbeux) sous peine de voire la durée de vie de votre SD se réduire très vite et j’en ai déjà tué trois (ok j’ai 5 Pi mais bon) mais le plus pénible c’est que ce n’est pas immédiat, votre Pi commence à avoir un comportement bizarre, à déconner, à planter et vous cherchez pourquoi alors qu’au final c’est “juste” la SD qui est en train de mourir.

Et c’est pour çà que le Pi, pour les démos et les tests çà me va, mais jamais de la vie en production, ou alors il faut mettre le filesystem en read-only comme décrit dans mon article dédié sur le sujet.

Edit du 25 Mai 2015

Pour information, je vous montre le workflow de ma production mis à jour récemment. Il tourne sur un vieux plug dédié (sheeva plug) sur lequel j’ai mis ma carte USB Micro Teleinfo. Le tout tourne avec node red, vous y noterez quelques différences :

  • j’y alimente le plugins teleinfo de Jeedom
  • J’alimente 2 bases Emoncms.
  • le dongle Micro Teleinfo est vu comme une liaison série (/dev/ttyUSB0)
  • J’ai encore 2/3 processus qui écoutent les données de téléinfo envoyées par le daemon teleinfo broadcast en UDP, d’ou les 2 blocs UDP broadcast, mais vous n’en avez pas besoin.
  • La fonction
    Valider Trame

    est maintenant commune (çà evite les copier/coller de code)

  • La fonction
    Convertir Etiquettes

    prépare la dernière trame reçue pour une insertion en base emoncms. Ensuite elle est sauvé dans le contexte de node red (en temps réel), et ce sont les injecteurs (plus précis que la méthode décrite dans cet article précédement) 10s et 5m qui reprennent la dernière trame sauvée dans le contexte afin de les envoyer sur emoncms

  • Toutes les 10 secondes je mets à jour les données temps réel (ADPS, IISINT et PAPP et TENSION)
  • Toutes les 5 minutes je mets à jour toutes les données
Node Red Teleinfo Production

Node Red Teleinfo Production

Vous trouverez ci-dessous les flows de ma production

Valider Trame

// La trame complète est reçue dans 'msg'
var teleinfo={};

// Enlever les codes début et fin de trame et récupérer les lignes 1 à 1
var lines = msg.payload.toString().replace("\u0002\n","").replace("\r\u0003","");
lines = lines.split("\r\n");

// Pour chaque ligne
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 ) {
		teleinfo[label] = value;
	} else {
		console.log("'%s' '%s' '%s' => Bad Checksum '%s'", label, value, check, checksum );
	}
}
return [ { payload: teleinfo } ];

Convertir Etiquettes

function isNumeric(n) { 
      return !isNaN(parseFloat(n)) && isFinite(n); 
}

// Pour tous les labels 
for (var label in msg.payload ) {
    var value = msg.payload[label];
    
	// Correction des valeurs type string en numérique 		
	if (label == "OPTARIF")	{
  		// L'option tarifaire choisie (Groupe "OPTARIF") est codée sur 4 caractères alphanumériques 
  		// J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous 
  		// je mets le 4eme char à 0, trop de possibilités 
      	value = value.substring(0, 3);
    
       	if      (value=="BAS") value=1;// BASE => Option Base. 
  		else if (value=="HC.") value=2;// HC.. => Option Heures Creuses. 
  		else if (value=="EJP") value=3;// EJP. => Option EJP. 
  		else if (value=="BBR") value=4;// BBRx => Option Tempo
  		else value = 0;
  		
  		msg.payload[label] = value;
	} else if (label=="HHPHC") {
      // L'horaire heures pleines/heures creuses (Groupe "HHPHC") est codé par un caractère A à Y 
      // J'ai choisi de prendre son code ASCII
      msg.payload[label] = value.charCodeAt();
    } else if ( label == "PTEC") {
      // La période tarifaire en cours (Groupe "PTEC"), est codée sur 4 caractères 
      // J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous
      if      (value=="TH..") value= 1; // Toutes les Heures. 
      else if (value=="HC..") value= 2; // Heures Creuses. 
      else if (value=="HP..") value= 3; // Heures Pleines. 
      else if (value=="HN..") value= 4; // Heures Normales. 
      else if (value=="PM..") value= 5; // Heures de Pointe Mobile. 
      else if (value=="HCJB") value= 6; // Heures Creuses Jours Bleus. 
      else if (value=="HCJW") value= 7; // Heures Creuses Jours Blancs (White). 
      else if (value=="HCJR") value= 8; // Heures Creuses Jours Rouges. 
      else if (value=="HPJB") value= 9; // Heures Pleines Jours Bleus. 
      else if (value=="HPJW") value= 10;// Heures Pleines Jours Blancs (White). 
      else if (value=="HPJR") value= 11;// Heures Pleines Jours Rouges. 
      else value = 0;
      
      msg.payload[label] = value;
    } else if ( label == "IINST") {
        delete msg.payload.IINST;
        msg.payload.IINST1 = (msg.payload.PAPP/msg.payload.TENSION).toFixed(3);
    } else if ( label == "IMAX") {
        delete msg.payload.IMAX;
        msg.payload.IMAX1 = Number(value);
    } else if ( isNumeric(value) && label != "ADCO" ) {
        // Transformer les valeurs numériques
        msg.payload[label] = Number(value);
    }
}

// Sauvegarde dans le contexte global
context.global.teleinfo = msg.payload;

return msg;

Valeurs Temps Réel

var str = "";
var ti = context.global.teleinfo;

for (var label in ti) {
	if (label=="ADPS" || label=="PAPP" || label=="TENSION" || label=="IINST1" || label=="IMAX1" ) {
         if (str.length>0)
            str+=","
            
         str += label + ":"+ ti[label];
	}
}
return [ { payload: str } ];

Toutes Valeurs

var str = "";
var ti = context.global.teleinfo;

for (var label in ti) {
    if (str.length>0)
        str+=","

    str += label + ":"+ ti[label];
}

return [ { payload: str } ];

Trame vers URL

// La trame complète est reçue dans 'msg'
var str = "";

for (var label in msg.payload )
	str += "&" + label + "=" + msg.payload[label];	

return [ { url: "http://jeedom.local/jeedom/plugins/teleinfo/core/php/jeeTeleinfo.php?api=votre_api_jdom" + str,
           method: "GET" 
       } ];

Configurer ensuite le nœud Envoi Msg sur JDOM avec l’URL à vide (elle est pré-remplie avec le code ci-dessus) et mettre la méthode avec “set my msg.method”

Références

Vous trouverez tout ce qu’il faut pour construire la carte PiTInfo sur mon github dans le dossier PiTInfo du repository teleinfo

Il me reste quelques cartes après mes tests, alors comme promis dans le titre, elles sont disponibles pour moins de 10€ sur Tindie

 

I sell on Tindie

Charles

You can discuss about this article or other project using the community forum