Télé-information client des compteurs EDF

Compteur électronique SAGEM S10-C4

Un Raspberry Pi pour récupérer de manière régulière et automatique les informations d'un compteur électronique d'électricité de votre distributeur préféré (alterna, direct energie, happ'e, proxelia, lampiris, engie, planete oui, edf, énergem, enercoop …) : intensité et puissance instantanées, index et autres.

On pourrait peut-être s'appuyer sur un Rabperry Pi, voir un Rabperry Pi Zero pour réaliser un auto relevé. Les inconvénients sont les suivants :

  • pas de prise Ethernet (propre sur Rabperry Pi Zero)
  • pas de prise USB type A pour y brancher un dongle Wifi (propre sur Rabperry Pi Zero)
  • obligation d'avoir une alimentation en 5 V.

Concernant l'alimentation, voici les pistes de réflexion :

  • déport du Raspberry Pi par rapport au compteur électronique
  • alimentation par la compteur

Déport du Raspberry Pi

Les caractéristiques physiques du câble à utiliser entre le RasbperryPi et le bus de télé-information client sont celles d’un câble téléphonique intérieur de type suivant:

  • paire torsadée simple avec écran (aluminium) et conducteur de drain,
  • conducteurs monobrins en cuivre étamé de diamètre compris entre 0,5 mm et 0,6 mm,
  • isolant PVC.

En utilisation, la longueur du bus mis en œuvre doit est inférieure ou égale à 500m (en topologie quelconque). Ce qui n'oblige pas à disposer le RasbperryPi à proximité du compteur.

Concernant les Rabperry Pi Zero :

Alimentation de la TIC

L’accès au circuit d’alimentation de la TIC se fait via les bornes I1 et A. Ce circuit est mis à disposition des clients pour alimenter un récepteur de télé-information rattaché au compteur.

Lorsque aucune charge n’est raccordée à la sortie de l’alimentation de la TIC, la tension aux bornes de l’alimentation vaut 13 Vrms max.

En charge, la tension est 6 Vrms ±10% à 50 kHz (12 V pic au maximum tenant compte d’éventuelles déformations du signal).
La puissance minimale délivrée est de 130 mW.
Il convient de protéger la sortie doit être protégée contre les court-circuits. La tenue à la tension secteur (230 V 50Hz) est exigée (en cas de branchement intempestif de l’installation client).

Mise en oeuvre

Pour réaliser l'interface entre le bornier TIC et le Raspberry Pi, j'ai acheté :

  • une plaque pré-percée
  • 2 résistances
  • un opto-coupleur
  • bornier
  • câbles pour connecter au Raspberry Pi - 3
  • câble pour relier au bornier TIC - câble réseau
Modèle A Modèle A+ Modèle B Modèle B+ Modèle Zero Modèle 2
clé Wifi obligatoire obligatoire en option en option obligatoire en option
boitier oui compliqué compliqué oui oui oui

à suivre Câblage et Réalisation du circuit de conversion


Système d'exploitation utilisé

Pour la suite des évènements, je me suis basé sur Raspbian v.8 (Jessie).

Pour connaitre la version de votre Raspbian, il suffit de consulter le fichier /etc/os-release.

Il vous sortira un code ce genre :

PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

uname vous permettra de connaitre la version de Linux :

Installation de l'OS (Système d'exploitation)

Je vous invite à lire la section sur l'installation de Raspbian. Vous apprendrez comment déployer Raspbian sur une carte SD depuis une image téléchargée sur le site Raspberry.

Je vous conseillerai des paramètres de configuration fort utile.

Mise à jour de Raspbian

N’hésitez pas à suivre les instructions suivantes pour mettre à jour votre Raspbian.
Suivez ces indications, même si vous venez de télécharger et installer Raspbian sur votre Rapberry Pi.

https://www.youtube.com/watch?v=MErKTQ3HG1c


Le Raspberry Pi propose plusieurs protocoles de communication, dont l'UART. Il est connu sous le nom de ttyAMA0. Il sera exploité avec le chemin /dev/ttyAMA0.

Désactiver console sur ttyAMA0

Au démarrage, le noyau propose un terminal par le liaison série. Il va falloir le désactiver.

Pour supprimer l’utilisation de l’UART au démarrage par le noyau, il faut éditer le fichier /boot/cmdline.txt, supprimer les options console=ttyAMA0,115200 kgdboc=ttyAMA0,115200.

Dans la version de Raspbian que j'ai, l'option kgdboc=ttyAMA0,115200 n'était pas présent dans le fichier /boot/cmdline.txt.
On notera également que l'action suivante n'était pas nécessaire. En effet, le fichier /etc/inittab n'était pas présent.

Pour désactiver la console sur l'UART, il faut commenter les lignes suivantes dans le fichier /etc/inittab :

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Configurer la liaison UART

La liaison /dev/ttyAMA0 est configurée pour vous renvoyer un écho de ce qu’elle reçoit. La liaison se configure avec stty :

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

Il sera judicieux d'effectuer cette commande à chaque fois que le Raspberry Pi démarrera.

Visualiser les premières trames

cat /dev/ttyAMA0

et le résultat est


ADCO 020122037669 =
OPTARIF HC.. <
ISOUSC 45 ?
HCHC 118261467 *
HCHP 069574256 ?
PTEC HP..  
IINST 007 ^
IMAX 045 H
PAPP 01570 .
HHPHC C .
MOTDETAT 000000 B

Voici le principe de fonctionnement que je voulais faire initialement :

  1. lecteur des informations sur le port série (coté local)
  2. envoie sur serveur de base de données SGBD (coté serveur)

On y reviendra plus tard.

Pour l'instant j'installe tout sur le raspberyPi.

Installer PHP

La lecture sur des informations va s'effectuer en PHP. C'est le plus simple pour moi parce que c'est très proche du langage C. Dans un premier temps il faut installer l’interpréteur PHP :

sudo apt-get install php

On s’aperçoit que l'installation du package PHP intègre d'autres composants.

On retrouve Apache2 et des fonctions associées à SQLite3, LDAP et JSON.

Plusieurs fichiers de configuration sont créés :

  • /etc/php/7.0/apache2/php.ini
  • /etc/php/7.0/cli/php.ini
  • fichiers présents dans /etc/php/7.0/mods-available/

Deux binaires sont accessibles :

  • php
  • phar
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances       
Lecture des informations d'état... Fait
The following additional packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php7.0 libapr1 libaprutil1
  libaprutil1-dbd-sqlite3 libaprutil1-ldap php-common php7.0 php7.0-cli php7.0-common php7.0-json
  php7.0-opcache php7.0-readline ssl-cert
Paquets suggérés :
  apache2-doc apache2-suexec-pristine | apache2-suexec-custom php-pear openssl-blacklist
Les NOUVEAUX paquets suivants seront installés :
  apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php7.0 libapr1 libaprutil1
  libaprutil1-dbd-sqlite3 libaprutil1-ldap php php-common php7.0 php7.0-cli php7.0-common php7.0-json
  php7.0-opcache php7.0-readline ssl-cert
0 mis à jour, 18 nouvellement installés, 0 à enlever et 0 non mis à jour.
Il est nécessaire de prendre 4 582 ko dans les archives.
Après cette opération, 17,0 Mo d'espace disque supplémentaires seront utilisés.
Souhaitez-vous continuer ? [O/n]

Installer le SGBD PostgreSQL

J'ai installé le SGBD PostgreSQL ainsi que le bibliothèque de connexion PHP.

Une fois installé, les programmes n'occuperont que 30 Mo. Je n'ai pas l'habitude d'avoir une installation prenant aussi peu de place.

sudo apt-get install php-pgsql postgresql

Résultat :

Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances       
Lecture des informations d'état... Fait
The following additional packages will be installed:
  libpq5 php7.0-pgsql postgresql-9.6 postgresql-client-9.6 postgresql-client-common postgresql-common
  postgresql-contrib-9.6 sysstat
Paquets suggérés :
  postgresql-doc locales-all postgresql-doc-9.6 libdbd-pg-perl isag
Les NOUVEAUX paquets suivants seront installés :
  libpq5 php-pgsql php7.0-pgsql postgresql postgresql-9.6 postgresql-client-9.6
  postgresql-client-common postgresql-common postgresql-contrib-9.6 sysstat
0 mis à jour, 10 nouvellement installés, 0 à enlever et 0 non mis à jour.
Il est nécessaire de prendre 6 281 ko dans les archives.
Après cette opération, 30,2 Mo d'espace disque supplémentaires seront utilisés.
Souhaitez-vous continuer ? [O/n] 

Paramétrer le SGBD PostgreSQL

Voilà comment je fais pour me connecter au moteur de SGBD PostgreSQL. J'effectue ces manipulations depuis le compte pi.

1. Je me connecte avec le compte du SGBD qui se nomme postgres :

sudo su postgres

2. Je me connecte au SGBD :

psql

Oh joie ! L'invite postgres=# apparaît.

Créer la base de données

Je vais utiliser les informations suivantes :

  • base de données : ampere
  • utilisateur de la base de données (rôle) : r_ampere

Il faut créer l'utilisateur de la base de données. De manière schématique, l'utilisateur de connexion à la base de données s'appelle un rôle.

Création du rôle r_ampere

CREATE ROLE r_ampere PASSWORD 'This1sN0tAnPwd' LOGIN VALID UNTIL 'infinity'; 

Il faut créer la base de données qui va accueillir les données.

J'ai choisi d'utiliser l'encodage UTF-8 dans la base de données, et l'utilisation des règles de la langue Française (fr_FR).

CREATE DATABASE "ampere"
WITH OWNER "r_ampere"
ENCODING 'UTF8'
LC_COLLATE = 'fr_FR.UTF-8'
LC_CTYPE = 'fr_FR.UTF-8';

Il faut autoriser les connexions. Pour cela, le fichier de configuration des clients authentifié doit être adapté. Lors de l'installation du SGBD, il a été créé dans /etc/postgresql/9.6/main/pg_hba.conf

Il faut l'adapter suivant le schéma suivant :

host       database  user  address  auth-method

On s'identifie avec l'utilisateur postgres :

pi: $ sudo su - postgres

On ajoute dans le fichier /etc/postgresql/9.6/main/pg_hba.conf :

local       ampere  r_ampere    trust

On sort de l'environnement postgres :

postgres: $ exit

Une fois le paramétrage terminé, il faut redémarrer le SGBD :

pi: $ sudo service postgresql reload

On teste la connexion :

pi: $ psql -U r_ampere -W -d ampere

Principe de fonctionnement

Un programme doit sans cesse boucler pour effectuer cette action :

1. lire une trame sur /dev/ttyAMA0                                   readTrame
2. ajouter un timestamp dans la trame                               
3. mémoriser la trame brute avec timestamp dans une mémoire tampon - saveTrameTampon

saveTrameBdd

saveTrameCsv

Insérer une fichier CSV dans une table MySQL

<?php
$databasehost = "localhost"; 
$databasename = "telereleve_elec"; 
$databasetable = "tr_journalier"; 
$databaseusername="Utilisateur"; 
$databasepassword = "motDePasse"; 
$fieldseparator = ","; 
$lineseparator = "\n";
$csvfile = "releves/teleinfo_20181219.csv";
 
if(!file_exists($csvfile)) {
    die("File not found. Make sure you specified the correct path.\n");
}
 
try {
    $pdo = new PDO("mysql:host=$databasehost;dbname=$databasename", 
        $databaseusername, $databasepassword,
        array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        )
    );
} catch (PDOException $e) {
    die("database connection failed: ".$e->getMessage());
}
 
$affectedRows = $pdo->exec("
    LOAD DATA LOCAL INFILE ".$pdo->quote($csvfile)." INTO TABLE `$databasetable`
      FIELDS TERMINATED BY ".$pdo->quote($fieldseparator)."
      LINES TERMINATED BY ".$pdo->quote($lineseparator));
 
echo "Loaded a total of $affectedRows records from this csv file.\n";
 
?>

Transformer une donnée timestamp unix en format date et heure

SELECT FROM_UNIXTIME(`TIMESTAMP`) FROM `tr_journalier`

Bibliothèque PHP

Le programme sera écrit en PHP. On va au maximum utiliser des méthodes afin d'obtenir des informations sur la consommation :

  • quelle est la consommation Intensité instantannée ? - getIINST
  • quelle est la valeur du compteur HC ? - getHCHC
  • quelle est la valeur du compteur HP ? - getHCHP
  • quelle est la période tarifaire en cours ? - getPTEC
  • quelle est la puissance apparente ? - getPAPP

et obtenir des informations sur l'abonnement :

  • quelle est le N° d’identification du compteur ? - getADCO
  • quelle est l'Option tarifaire ? - getOPTARIF
  • quelle est l'Intensité souscrite ? - getISOUSC

Je pense également à des méthodes d'analyse :

  • quelle est la consommation HC/HP de la période tarifaire actuelle ? - getConsoPeriodeNow(tarif)
  • quelle est la consommation HC/HP de la période précédente ? - getConsoPeriodePrev(tarif)
  • quelle est la consommation HC/HP des 24 dernières heures ? - getConsoPeriode24(tarif)
  • quelle est la consommation HC/HP d'une période de 7 jours X ? - getConsoPeriode7jours(tarif, dateHeureDebut)
  • quelle est la consommation HC/HP de la minute X ? - getConsoMinute(tarif, dateHeure)
  • quelle est la consommation HC/HP de l'heure X ? - getConsoHeure(tarif, dateHeure)
  • quelle est la consommation HC/HP du jour X ? - getConsoJour(tarif, dateHeure)
  • quelle est la consommation HC/HP de la semaine X ? - getConsoSemaine(tarif, date)
  • quelle est la consommation HC/HP du mois X ? - getConsoMois(tarif, date)
  • quelle est la consommation HC/HP de l'année X ? - getConsoAnnee(tarif, date)

Et ensuite on pourra partir sur des statistiques :

  • moyenne
  • tendance

Projets

  • informatique/raspberry-pi/teleinformation_compteur_edf/start.txt
  • Dernière modification: 2019/01/04 04:30
  • par Cedric ABONNEL