[***] Téléinfo - Linux & PHP

Solution à base d'un PC et d'un logiciel (Misterhouse, Domotiga, Heyu, etc). Vous trouverez ici de l'aide pour installer, configurer ou développer des scripts sur ces logiciels. Les principaux langages sont Perl, Java, Shell Unix, Php, etc

[***] Téléinfo - Linux & PHP

Messagede acidoracle » 31 Oct 2007, 21:28

Bonjour,

j'ai cherché sur le web comment accéder sous Linux aux informations du compteur électrique (téléinfo) mais je n'a rien trouvé alors j'ai décidé de programmer une bibliothèque PHP qui réalise cette tâche.

teleinfo.php (nouvelle version)
Code: Tout sélectionner
<?php
/*
* PHP-Teleinfo
* v.0.2
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*  (c) 2008 Radim BADSI <info AT devbay DOT fr>
*/

/* Definition des messages */
function mesdef() {
   $trame_def = array();
   $trame_def["OPTARIF"] = array(
                     "size"=>4,
                     "desc"=>"type d'abonnement",
                     "unit"=>""
                     );
   
   $trame_def["ADCO"] = array(
                     "size"=>12,
                     "desc"=>"numĂ©ro sĂ©rie compteur",
                     "unit"=>""
                     );
   $trame_def["ISOUSC"] = array(
                     "size"=>2,
                     "desc"=>"intensitĂ© souscrite",
                     "unit"=>"A"
                     );
                     
   $trame_def["BASE"] = array(
                     "size"=>9,
                     "desc"=>"index (base)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["HCHC"] = array(
                     "size"=>9,
                     "desc"=>"index (heures creuses)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["HCHP"] = array(
                     "size"=>9,
                     "desc"=>"index (heures pleines)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["EJP HN"] = array(
                     "size"=>9,
                     "desc"=>"index (normal EJP)",
                     "unit"=>"Wh"
                     );
   
   $trame_def["EJP HPM"] = array(
                     "size"=>9,
                     "desc"=>"index (pointe mobile EJP)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["BBR HC JB"] = array(
                     "size"=>9,
                     "desc"=>"index (heures creuses jours bleus Tempo)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["BBR HP JB"] = array(
                     "size"=>9,
                     "desc"=>"index (heures pleines jours bleus Tempo)",
                     "unit"=>"Wh"
                     );
   
   $trame_def["BBR HC JW"] = array(
                     "size"=>9,
                     "desc"=>"index (heures creuses jours blancs Tempo)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["BBR HP JW"] = array(
                     "size"=>9,
                     "desc"=>"index (heures pleines jours blancs Tempo)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["BBR HC JR"] = array(
                     "size"=>9,
                     "desc"=>"index (heures creuses jours rouges Tempo)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["BBR HP JR"] = array(
                     "size"=>9,
                     "desc"=>"index (heures pleines jours rouges Tempo)",
                     "unit"=>"Wh"
                     );
                     
   $trame_def["PEJP"] = array(
                     "size"=>2,
                     "desc"=>"prĂ©avis pĂ©riode EJP",
                     "unit"=>""
                     );
                     
   $trame_def["PTEC"] = array(
                     "size"=>4,
                     "desc"=>"pĂ©riode tarifaire en cours",
                     "unit"=>""
                     );
   
   $trame_def["DEMAIN"] = array(
                     "size"=>1,
                     "desc"=>"couleur du lendemain (Tempo)",
                     "unit"=>""
                     );
                     
   $trame_def["IINST"] = array(
                     "size"=>3,
                     "desc"=>"intensitĂ© instantanĂ©e",
                     "unit"=>"A"
                     );
                     
   $trame_def["ADPS"] = array(
                     "size"=>3,
                     "desc"=>"avertissement de dĂ©passement de la puissance souscrite",
                     "unit"=>""
                     );
                     
   $trame_def["IMAX"] = array(
                     "size"=>3,
                     "desc"=>"intensitĂ© maximale",
                     "unit"=>"A"
                     );
   
   $trame_def["PAPP"] = array(
                     "size"=>5,
                     "desc"=>"puissance apparente",
                     "unit"=>"W"
                     );
   
   $trame_def["HHPHC"] = array(
                     "size"=>1,
                     "desc"=>"groupe horaire (Tempo/HC)",
                     "unit"=>""
                     );
                     
   $trame_def["MOTDETAT"] = array(
                     "size"=>6,
                     "desc"=>"mot d'Ă©tat",
                     "unit"=>""
                     );
   /* Fin definition */
   return $trame_def;
}

/* Verifie le checksum d'un message */
function checksum ($etiquette, $valeur) {
   $sum = 32; // Somme des codes ASCII du message+un espace
   for ($i=0;$i<strlen($etiquette);$i++) {
      $sum = $sum + ord($etiquette[$i]);
   }
   for ($i=0;$i<strlen($valeur);$i++) {
      $sum = $sum + ord($valeur[$i]);
   }
   $sum = ($sum & 63) + 32;
   return (chr($sum));
}

/* Verifie la taille des messages */
function messize($etiquette) {
   $trame_def = mesdef();
   /* Renvoyer la taille d'une valeur valide */
   return $trame_def[$etiquette]["size"];
}

/* Ecrire la liste des etiquettes valides */
function etiqlist() {
   $trame_def = mesdef();
   foreach ($trame_def as $etiquette => $definition) {
      echo("<strong>$etiquette</strong> " .
          $definition["desc"] . "<br/>\n");
   }
}

/* Recuperer une trame valide */
function teleinfo ($port = "/dev/ttyS1") {
   // Resultat : liste etiquette=>valeur
   $trame_array = array();
   
   // Ouvrir le port en lecture
   $handle = fopen ($port, "r");

   $char = "";
   $contents = "";
   while (fread($handle, 1) != chr(2));

   do {
      $char = fread($handle, 1);
      if ($char != chr(2)) $contents .= $char;
   } while ($char != chr(2));


   // Fermer le port
   fclose ($handle);

   // Supprimer les caracteres debut/fin de trame
   $trame = substr($contents,1,-1);

   // Separer les messages
   $trame = explode(chr(10).chr(10), $trame);

   // Verifier les checksum et supprimer les trames incorrectes
   foreach ($trame as $key=>$message) {
      
      // Separer l'etiquette, la valeur et le checksum
      $message = explode (chr(32), $message, 3);
      list ($etiquette, $valeur, $checksum) = $message;
   
      // Supprimer le message si incomplet ou incorrect (checksum invalide)
      if (count($message)<3 ||
         checksum($etiquette, $valeur) != $checksum ||
         messize($etiquette) != strlen($valeur)
         ) {
         unset($trame[$key]);
      } else {
         // Enregistrer le message dans la liste trame_array
         $trame_array[$etiquette] = $valeur;
      }
   }
   
   return $trame_array;
}
?>


index.php (script de démonstration)
Code: Tout sélectionner
<?php
include ("teleinfo.php");
?>
<html>
<head>
   <title>TELEINFO</title>
</head>
<body>
<p>
<?php
foreach (teleinfo() as $etiquette=>$valeur) {
   echo("$etiquette <strong>$valeur</strong><br/>\n");
}
?>
</p>
</body>
</html>


Comme vous pouvez le remarquer, la fonction teleinfo() renvoie une trame sous forme d'une liste dont chaque élément correspond à un message (étiquette+valeur) :

Code: Tout sélectionner
array(11) {
  ["ADCO"]=>
  string(12) "050512342345"
  ["OPTARIF"]=>
  string(4) "HC.."
  ["ISOUSC"]=>
  string(2) "60"
  ["HCHC"]=>
  string(9) "009666222"
  ["HCHP"]=>
  string(9) "011597038"
  ["PTEC"]=>
  string(4) "HP.."
  ["IINST"]=>
  string(3) "002"
  ["IMAX"]=>
  string(3) "047"
  ["PAPP"]=>
  string(5) "00550"
  ["HHPHC"]=>
  string(1) "D"
  ["MOTDETAT"]=>
  string(6) "000000"
}


Attention ! Le compteur ne renvoie pas systématiquement tous les messages. De plus, lorsque le checksum (somme de contrôle) d'un message est incorrect, le message est ignoré (seuls les messages valides sont renvoyés).

Je paramètre le port série avec la commande suivante (à placer dans /etc/rc.local pour reconfigurer le port série au démarrage de l'ordinateur)

Code: Tout sélectionner
stty -F /dev/ttyS1 1200 sane evenp parenb cs7 -crtscts


A+

Acidoracle
Dernière édition par acidoracle le 05 Aoû 2008, 23:50, édité 2 fois.
X10 & 1-wire & Téléinfo-> Ubuntu Server 8.04
Avatar de l’utilisateur
acidoracle
Membre Actif
 
Messages: 29
Inscription: 06 FĂ©v 2006, 22:49
Localisation: Montpellier, FR

Messagede acidoracle » 24 DĂ©c 2007, 00:54

mochel a Ă©crit:salut

merci pour ton scrpt
comment l'utilise tu ? avec quel adatateur tu va lire les valeurs ?
comment en faire ensuite des exports de données ? des graphes ?
merci d'avance

pascal

et bonnes fĂŞtes


Salut,

le script peut être placé sur un serveur web (Apache). Il suffit alors d'aller sur la page web correspondante ou de l'exécuter directement (sans serveur web) en donnant son chemin d'accès comme paramètre à php.

teleinfo.php est une bibliothèque, elle contient les fonctions d'accès à la téléinformation. index.php est une petite page web de démonstration : elle affiche une trame complète (qui lui est renvoyée par teleinfo.php).

J'utilise le montage de dauguet qui marche très bien : http://teleinfo.dauguet.net/ (regarde dans "schéma"). Je crois que tout le monde utilise ce même schéma :P

Pour faire l'export de données, il faut écrire un petit script. Après, il faut voir par rapport à ce que tu voudrais faire, je peux mettre en ligne (si ça t'intéresse) un petit script qui enregistre périodiquement toutes les valeurs dans un fichier .csv lisible par un tableur. Pour les graphes, je te conseille jpgraph ou Open Flash Chart mais il faut programmer tout ça, mon script n'est qu'une bibliothèque...

Expliques moi un peu ce que tu voudrais faire :P Tu as quoi comme équipement (système d'exploitation etc.) ?

Bonnes fĂŞtes :)
X10 & 1-wire & Téléinfo-> Ubuntu Server 8.04
Avatar de l’utilisateur
acidoracle
Membre Actif
 
Messages: 29
Inscription: 06 FĂ©v 2006, 22:49
Localisation: Montpellier, FR

bonjour

Messagede mochel » 24 DĂ©c 2007, 09:48

et merci pour ta proposition de script
cela m'interesse beaucoup de pourvoir en faire un graphique et aussi bien sur de pouvoir l'exporter vers excel par exemple

si tu as le temps ..... merci d'avance
mochel
Membre un peu timide !
 
Messages: 3
Inscription: 07 Sep 2003, 18:51

Messagede MisterT » 19 Jan 2008, 20:06

Bonjour,

Je suis nouveau sur ce forum. Je suis à la recherche d'un moyen d'enregistrer ma consommation électrique instantanée (disons, à la minute ca serait bien), afin d'avoir une meilleure vision de mes (mauvaises) habitudes de consommation, et de les améliorer.

J'ai bien un compteur qui permet la téléinfo, et je suis donc intéressé par les solutions qui tournent autour.

acidoracle a écrit:J'utilise le montage de dauguet qui marche très bien : http://teleinfo.dauguet.net/ (regarde dans "schéma"). Je crois que tout le monde utilise ce même schéma :P


Oui, je l'avais trouvé également.
Je suis peu expérimenté en électronique, aussi je me demande si personne ne "vend" un module tout fait ?
Ou, mieux encore, un module faisant le lien entre le téléinfo, et un "bus" quelconque (X10, 1-wire, IP Wireless,...) ?
Le but étant de récupérer ces infos sur un PC, pas forcemment localisé à coté du compteur électrique !


acidoracle a écrit:Expliques moi un peu ce que tu voudrais faire :P Tu as quoi comme équipement (système d'exploitation etc.) ?


Ca, c'est une proposition sympa ! :lol:
Oui, je suis intéressé par un peu de code sous Linux. De préférence quelque chose de super "classique", comme du Perl ou même du Shell. Ceci parce que je n'ai pas trente six ordinateurs de branchés en permanence dans la maison: seul le firewall (IPCop) tourne 24x7, et je souhaite l'utiliser pour récupérer les données. Or, pour des raisons de sécurisation, cet ordinateur est équipé d'une distribution Linux minimale...
Une fois ces données dans un fichier, je saurai les exporter quelque part (par exemple sur Internet) et faire les pages de visualisation associées... Mais il me manque cette phase de récupération... Donc toute aide est la bienvenue !

Un grand merci d'avance,
MisterT
Membre un peu timide !
 
Messages: 2
Inscription: 19 Jan 2008, 19:53

Messagede b10489 » 19 Jan 2008, 21:57

j'ai importé les tableaux issus du programme "adauguet"...sur excel
d'abord un points 1' --> trop de données !
puis en points 5' pour voir nos mauvaises habitudes --> bien
maintenant le relevé est en point 1h et ça suffit...cele me permet de surveiller les consos tempo au jour le jour...
centrale domo "varuna 3" de chez HESTIA
gestion alarme,chauffage,délestage,domotique...
gestion portail
gestion des portes de garage avec automate Siemens logo!
11 détecteurs périmétriques + 3 IR
1 detecteur CO + 1 fumées
X10: 8 SW10, 5 am12, 2 ad 10, 2 ld11, 1 ms13, 1 douille,1 FD10, 1 TM13 (supprimé)
2 télécommandes IRIS
2 modules WES, un pour le général et un pour le chauffage (2 compteurs d'énergie)
12 sondes Dallas, comptage eau, comptage conso vmc et ECS sur un WES et 4 sur un autre.
un Ă©cran tactile 15" au mur avec le logiciel "mitra" (Hestia)
Avatar de l’utilisateur
b10489
Dieu de domotique
 
Messages: 549
Inscription: 30 DĂ©c 2006, 11:33
Localisation: Dunkerque

Messagede acidoracle » 19 Jan 2008, 23:22

Voici mon script d'acqusition qui utilise ma bibliothèque postée dans le premier message :

log.php
Code: Tout sélectionner
<?php
/*
* PHP-Teleinfo - script d'acqusition
* v.0.1.5
*
* Utilisation :
*  /usr/bin/php /var/www/dom/teleinfo/log.php >> /opt/dom/teleinfo.csv

*  Pour creer le fichier CSV :
*    /usr/bin/php /var/www/dom/teleinfo/log.php --header > /opt/dom/teleinfo.csv
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*  (c) 2007 Radim BADSI <info AT devbay DOT fr>
*/

/* Liste des messages a sauvegarder */
$messages = array("HCHP","HCHC","PAPP","PTEC");

/* Nombres d'essais maximum */
$jmax = 10;

/* Chemin d'acces a la bibliotheque PHP-Teleinfo */
$phpteleinfo_path = "/var/www/dom/teleinfo/teleinfo.php";


if ($argv[1] == "--header") {
   $csv = chr(34) . "Date" . chr(34) . ",";
   /* Generer l'en-tete */
   foreach($messages as $etiquette) {
      $csv .= chr(34) . $etiquette . chr(34) . ",";
   }

} else {
   /* Lire les messages */
   include ($phpteleinfo_path);
   
   $j = 0; // Nombre d'essais
   do {
      $csv = chr(34) . time() . chr(34) . ",";
      $valid_etiq = 0; // Nombre d'etiquettes valides recuperees
      sleep(2); // Attendre 1s avant chaque tentative
      $trame = teleinfo();
      foreach ($messages as $etiquette) {
         if ($trame[$etiquette]) {
            $valid_etiq++;
            $csv .= chr(34) . $trame[$etiquette] . chr(34) . ",";
         }
         $j++; // Incrementer le nombre d'essais
         if ($j >= $jmax) die();
      }   
   } while ($valid_etiq != count($messages));
}
/* Remplacer la derniere virgule par un saut a la ligne */
$csv = substr_replace($csv, "\n", -1, 1);


/* Afficher le CSV */
echo($csv);
?>


Les valeurs sont enregistrées dans un fichier CSV (Comma-separated values) lisible par un tableur.

N'oubliez pas de modifier les paramètres au début du script !

La commande /usr/bin/php /var/www/dom/teleinfo/log.php --header > /opt/dom/teleinfo.csv permet de créer le fichier CSV (/opt/dom/teleinfo.csv).

Pour effectuer l'acquisition périodiquement, il faudra rajouter le script dans votre crontab :
- Ouvrir le terminal
- Taper crontab -e
- Rajouter Ă  la fin du fichier :
Code: Tout sélectionner
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/bin/php /var/www/dom/teleinfo/log.php >> /opt/dom/teleinfo.csv     #Teleinfo logger

Je vous invite à utiliser un générateur d'entrées crontab pour définir la fréquence des acquisitions (dans l'exemple que je vous donne ici, une acquisition sera effectuée toutes les 5 minutes).

Vérifiez que l'utilisateur dispose de droits d'accès suffisants (fichier CSV en écriture et port série (/dev/ttyS0) en lecture).

Testé sous PHP 5.2.3 & Ubuntu Server 7.10
Dernière édition par acidoracle le 20 Jan 2008, 13:25, édité 1 fois.
X10 & 1-wire & Téléinfo-> Ubuntu Server 8.04
Avatar de l’utilisateur
acidoracle
Membre Actif
 
Messages: 29
Inscription: 06 FĂ©v 2006, 22:49
Localisation: Montpellier, FR

Messagede acidoracle » 19 Jan 2008, 23:38

MisterT a écrit:Oui, je l'avais trouvé également.
Je suis peu expérimenté en électronique, aussi je me demande si personne ne "vend" un module tout fait ?
Ou, mieux encore, un module faisant le lien entre le téléinfo, et un "bus" quelconque (X10, 1-wire, IP Wireless,...) ?
Le but étant de récupérer ces infos sur un PC, pas forcemment localisé à coté du compteur électrique !


Je crois qu'une personne sur ce forum fabrique des circuits imprimées ce qui facilite déjà énormément la mise en oeuvre de cette interface. Regarde dans la rubrique "Bons plans". Par contre, je crois qu'il n'existe aucune interface compteur-PC "grand-public" puisque la certification est chère.

Si ton compteur se trouve loin de ton ordi, tu peux utiliser par ex. une Fonera (qui est au fait un ordinateur embarqué) placée à côté du compteur et reliée par WiFi au réseau local de la maison. Si ça t'intéresse, je peux te donner plus de détails, je me suis servi d'une Fonera dans un de mes projets d'école d'ingénieur.

MisterT a écrit:Oui, je suis intéressé par un peu de code sous Linux. De préférence quelque chose de super "classique", comme du Perl ou même du Shell. Ceci parce que je n'ai pas trente six ordinateurs de branchés en permanence dans la maison: seul le firewall (IPCop) tourne 24x7, et je souhaite l'utiliser pour récupérer les données. Or, pour des raisons de sécurisation, cet ordinateur est équipé d'une distribution Linux minimale...
Une fois ces données dans un fichier, je saurai les exporter quelque part (par exemple sur Internet) et faire les pages de visualisation associées... Mais il me manque cette phase de récupération... Donc toute aide est la bienvenue !


Pour diverses raisons, j'ai développé ce projet en PHP (qui peut tourner en stand-alone, sans serveur web, un peu comme Perl) mais ça ne doit pas être trop difficile d'écrire la même chose en Perl.
X10 & 1-wire & Téléinfo-> Ubuntu Server 8.04
Avatar de l’utilisateur
acidoracle
Membre Actif
 
Messages: 29
Inscription: 06 FĂ©v 2006, 22:49
Localisation: Montpellier, FR

Messagede MisterT » 20 Jan 2008, 00:35

Bon... je vais tenter la fabrication du circuit en premier.
Ensuite la liaison avec le PC.
Enfin, j'essayerai de faire tourner le tout...

Du boulot en perspective, mais merci pour cette aide !
MisterT
Membre un peu timide !
 
Messages: 2
Inscription: 19 Jan 2008, 19:53

Messagede starIST » 25 Mar 2008, 12:04

Salut

C'est exactement ce que je cherchais mais j'avais juste une question je souhaiterais faire tourner cela sur mon NAS Synology DS207 mais je n'ai pas de port série, si je prends un adaptateur, est ce que cela va fonctionner de la même façon ?

Merci d'avance
starIST
Membre Actif
 
Messages: 32
Inscription: 31 Jan 2008, 18:45

Messagede starIST » 30 Mar 2008, 10:09

Heuuuu un p'tit up :D :D :D :D
starIST
Membre Actif
 
Messages: 32
Inscription: 31 Jan 2008, 18:45

Messagede starIST » 01 Avr 2008, 14:09

Bah personne pour m'aider ?
starIST
Membre Actif
 
Messages: 32
Inscription: 31 Jan 2008, 18:45

Messagede DaRkYoda » 01 Avr 2008, 14:29

starIST a Ă©crit:Bah personne pour m'aider ?


Ben ici t'es sur un forum domotique :)

Pas sur un forum qui parle de NAS Synology DS207 ...

Donc va plutot sur des forums liés à ce NAS pour avoir ce type de réponse ...
Avatar de l’utilisateur
DaRkYoda
Dieu de domotique
 
Messages: 1282
Inscription: 22 DĂ©c 2006, 17:15
Localisation: Clermont-Fd

Suivante

Retourner vers Logiciel - Les autres logiciels pour la domotique

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

Copyright © 2011 - Touteladomotique.com - Tous droits rĂ©servĂ©s
Les blogs partenaires : Abavala, Domo-Blog, Domotique34, Maison et Domotique