268 lines
8.9 KiB
Plaintext
268 lines
8.9 KiB
Plaintext
|
||
===== Coté informatique =====
|
||
|
||
Voici le principe de fonctionnement que je voulais faire initialement :
|
||
- lecteur des informations sur le port série (coté local)
|
||
- 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
|
||
|
||
<WRAP group round box>
|
||
<WRAP half column>
|
||
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''
|
||
|
||
</WRAP>
|
||
|
||
<WRAP half column>
|
||
<code>
|
||
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]
|
||
</code>
|
||
</WRAP>
|
||
</WRAP>
|
||
|
||
==== Installer le SGBD PostgreSQL ====
|
||
|
||
<WRAP group round box>
|
||
<WRAP half column>
|
||
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.
|
||
</WRAP>
|
||
|
||
<WRAP half column>
|
||
sudo apt-get install php-pgsql postgresql
|
||
|
||
Résultat :
|
||
|
||
<code>
|
||
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]
|
||
</code>
|
||
</WRAP>
|
||
</WRAP>
|
||
|
||
==== Paramétrer le SGBD PostgreSQL ====
|
||
|
||
<WRAP center round box>
|
||
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.
|
||
</WRAP>
|
||
|
||
==== 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''
|
||
|
||
<WRAP group round box>
|
||
<WRAP half column>
|
||
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''.
|
||
</WRAP>
|
||
<WRAP half column>
|
||
Création du rôle ''r_ampere''
|
||
CREATE ROLE r_ampere PASSWORD 'This1sN0tAnPwd' LOGIN VALID UNTIL 'infinity';
|
||
</WRAP>
|
||
</WRAP>
|
||
|
||
<WRAP group box round>
|
||
<WRAP half column>
|
||
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'').
|
||
</WRAP>
|
||
|
||
<WRAP half column>
|
||
CREATE DATABASE "ampere"
|
||
WITH OWNER "r_ampere"
|
||
ENCODING 'UTF8'
|
||
LC_COLLATE = 'fr_FR.UTF-8'
|
||
LC_CTYPE = 'fr_FR.UTF-8';
|
||
</WRAP>
|
||
</WRAP>
|
||
|
||
<WRAP group box round>
|
||
<WRAP half column>
|
||
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
|
||
|
||
|
||
</WRAP>
|
||
|
||
<WRAP half column>
|
||
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
|
||
|
||
</WRAP>
|
||
</WRAP>
|
||
|
||
==== 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 ====
|
||
<code PHP>
|
||
<?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";
|
||
|
||
?>
|
||
</code>
|
||
|
||
|
||
==== 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 ===
|
||
|
||
http://vesta.homelinux.free.fr/wiki/demodulateur_teleinformation_edf.html
|
||
|
||
http://lhuet.github.io/blog/2014/01/montage-teleinfo.html
|
||
|
||
Projet de http://www.magdiblog.fr/gpio/teleinfo-edf-suivi-conso-de-votre-compteur-electrique/
|
||
|
||
Le relevé d'info compatible http://hallard.me/teleinfo-emoncms/
|
||
|
||
|