Archives par mot-clé : packagist

Télé relève EDF automatique

Après avoir cherché de nombreuses fois la meilleure méthode pour suivre la consommation électrique de la maison, je suis tombé sur un gazouillis qui parlait du télé-relevé EDF côté client.

Puis une recherche Google plus loin, je suis arrivé sur cette page. Les gros avantages de cet exemple pour moi sont que la réalisation a été faite sur un Raspberry Pi et que le code est en PHP. Pour les premiers tests cela fut bien pratique.

Me voilà reparti à réaliser un montage électronique. Le dernier montage était il y a 3 ans maintenant.

Grâce à un généreux collège qui a déjà réalisé la performance, j’ai pu obtenir le bon optocoupleur. Deux résistances plus tard, un câble posé entre le compteur et le Raspberry Pi, me voici parti dans le dur du sujet.

Comme présenté dans le lien donné plus haut, il y a quelques modifications à réaliser dans la configuration du Raspberry Pi  avant de connecter le câble sur le port GPIO.

Ensuite, vient la création du port série. Cette création est rapidement réalisée par la commande suivante  stty -F /dev/ttyAMA0 1200 sane evenp parenb cs7 -crtscts

Avant l’exécution de la commande, soit le fichier /dev/ttyAMA0 n’existe pas, soit il est muet lors de l’exécution de la commande cat.

Malheureusement, après un redémarrage du Raspberry Pi, le fichier est muet. Afin de palier ce problème, il est nécessaire d’ajouter la commande de création du port série à la cron tab (tâche planifiée) de l’utilisateur root.

Pour modifier la crontab :

sudo crontab -e

Ligne ajoutée :

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

Maintenant la commande cat /dev/ttyAMA0 affiche bien les données du télé-relevé après un redémarrage du Raspberry Pi.

Ensuite, étant développeur PHP, j’ai testé les scripts fournis dans l’article mais, n’étant pas pleinement satisfait, j’ai développé une application un peu plus moderne. Une fois développée, je me suis aperçu que le Raspberry ne disposait que de PHP 5.4 qui est incompatible avec mon travail (PHP 5.6 minimum).

Peu importe, PHP est libre, je vais le compiler. Et tant qu’à faire de le compiler, autant prendre la dernière version de PHP 7.0 pour profiter des nombreuses optimisations réalisées sur cette version. Afin de vous épargner bon nombre de désagréments, je vous fournis les commandes permettant la compilation de PHP 7.0 sur un Raspberry Pi A avec Raspbian 7.

Récupération des sources (les commandes durent longtemps) :

cd /home/pi

git clone https://github.com/php/php-src.git
cd php-src
git checkout PHP-7.0.6

## Si vous avez déjà les sources et pour récupérer la dernière version :
cd /home/pi/php-src
git checkout master
git clean -d -x -f
git reset --hard
git pull
git checkout PHP-7.0.6

Maintenant, il faut installer les librairies et outils nécessaires à la compilation de PHP :

sudo apt-get install -y make git autoconf automake libtool re2c bison g++ gcc libxml2 libxml2-dev libicu48 libicu-dev libjpeg-dev libpng12-dev libpng12 libzip2 libzip-dev libz1 libz-dev libt1-5 libt1-dev libvpx1 libvpx1-dev libxpm4 libxpm-dev libfreetype6 libfreetype6-dev libkrb5-dev libmemcached-dev libonig2 libqdbm14 lsof

La commande va mettre un certain temps à tout télécharger et installer les packets.

Ajouter le fichier /home/pi/buildphp2 avec le contenu suivant :

#!/bin/sh

rm -rf /opt/php7

mkdir /opt/php7

cd /home/pi/php-src

make clean

./buildconf --force

./configure --prefix=/opt/php7 --enable-fpm --with-libxml-dir=/usr/lib/arm-linux-gnueabihf/ --enable-bcmath --enable-exif --enable-intl --enable-pcntl --enable-calendar --enable-zip --enable-soap --enable-ftp --enable-mbstring --with-openssl --with-mcrypt --with-curl --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-zlib --with-bz2 --with-config-file-path=/opt/php7/etc/ --with-config-file-scan-dir=/opth/php7/etc/modules/ --with-sqlite3 --with-pdo-sqlite

make

make install

PHP est compilé puis installé dans /opt/php7 . Les fichiers de configuration de PHP sont disponibles dans le dossier /opt/php7/etc/ 

Commande permettant de lancer le script de compilation (à executer depuis la console du Raspberry Pi) :

/bin/sh /home/pi/buildphp2 >> /home/pi/buildLog.log 2>&1

La compilation a duré 4h15 sur mon Raspberry Pi A.

Une fois la compilation réalisée, un petit test s’impose :

pi@raspberrypi ~ $ /opt/php7/bin/php -v

PHP 7.0.6 (cli) (built: May  1 2016 00:47:02) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

pi@raspberrypi ~ $ /opt/php7/bin/php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
hash
iconv
intl
json
libxml
mbstring
mcrypt
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
soap
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zip
zlib

[Zend Modules]

Il y a plus de module car j’ai compilé quelques extensions complémentaires.

Afin de rendre PHP plus facile à utiliser nous allons créer un raccourci :

sudo ln -s /opt/php7/bin/php /usr/local/bin/php

Maintenant que PHP 7 est compilé et opérationnel, il est temps d’installer le programme de télé-relève.

Pour le télécharger, rien de plus simple. Tout comme pour PH,  l’utilisation de GIT est recommandée.

cd /home/pi
git clone https://github.com/Mactronique/edf-telereleve.git telereleve
cd telereleve

Maintenant, nous sommes dans le dossier de l’application. La première chose à faire est de télécharger la dernière version du gestionnaire de dépendances Composer.

Une fois installé, installons les dépendances du logiciel :

$ composer install --no-dev -o

Après la fin du téléchargement et de l’installation, le logiciel doit être configuré à minima en ajoutant ceci dans le fichier config.yml  situé à la racine du projet :

compteur: CBEMM
device: /dev/ttyAMA0

Le type de compteur correspond à la version la plus courante (doc EDF).

Maintenant vérifions que tout fonctionne bien :

pi@raspberrypi ~/telereleve $ ./telereleve
Mactronique EDF Telereleve Reader version 0.1

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  count
  help   Displays help for a command
  list   Lists commands
  read
  test

Vérifions que la lecture se passe bien :

Screen Shot 2016-05-26 at 22.37.27

Maintenant que tout fonctionne bien, il reste à mettre en place la dernière chose nécessaire à la réalisation d’un relevé toutes les 5 minutes.

Modifions la crontab de l’utilisateur pi crontab -e pour y ajouter la ligne suivante :

*/5 * * * * cd /home/pi/telereleve && /opt/php7/bin/php telereleve read >> telereleve.log

Que se passera-t-il toutes les 5 mins ? Le gestionnaire de tâches planifiées exécutera la commande « read » de mon application et stockera le relevé dans une base de données sqlite nommé « datas.sqlite ». Elle est située à la racine du projet. Afin de pouvoir vérifier ce qui s’est passé lors de l’exécution, le log est disponible dans le fichier « telereleve.log » également situé à la racine du projet.

Voici un exemple des données présentes dans la base de données (j’ai lu la base de données avec sqlite browser).

Screen Shot 2016-05-26 at 22.48.49

Les données sont exprimées en Wh. Il faut diviser par 1000 pour obtenir des KWh.

Merci de votre intérêt pour mon travail. Je suis impatient de lire vos retours d’expérience et vos commentaires sur le projet.

Mettre à jour un projet Symfony 2

Dans cet article qui me servira d’aide mémoire, je vais tenter de vous présenter ma méthode de mise à jour d’un projet Symfony 2.

Cette méthode vaut ce qu’elle vaut mais je n’ai rien trouvé de tel sur internet ! Même en anglais.

Plantons le décor

Nous avons un projet qui fonctionne avec Symfony 2.2.11 et nous souhaitons le faire passer sur la version LTS de Symfony 2 soit la version 2.3.x. En effet, la branche 2.2 n’est plus maintenue.

Comme de nombreux projets, j’utilise des librairies et bundles tiers gérés via l’utilitaire Composer.

Avant de rentrer dans le vif du sujet et, comme je compte pouvoir revenir en arrière, je commence par installer mon application dans un nouveau dossier. L’application doit fonctionner parfaitement avant la mise à jour.

Maintenant que nous avons notre application installée, voyons comment mettre à jour les librairies.

Récupération de la version cible

 

Sur le site de l’éditeur de Symfony, je commence par télécharger la version souhaitée du framework sans les vendors (without vendors). Ou je télécharge depuis le dépôt GitHub de la standard edition pour Symfony jusqu’à 3.4 ou le dépôt GitHub du Website Skeleton pour Symfony 4 et plus.

Dans l’archive, je récupère le fichier « composer.json » afin de le comparer à celui du projet.

Lors de la comparaison, je modifie le fichier « composer.json » de mon projet et modifie les versions des packages.

Mise à jour des librairies tierces

Pour les librairies tierces, j’utilise le site packagist pour vérifier la compatibilité de chaque version utilisée. Au besoin, je recherche la version compatible et je change également la version dans le fichier « composer.json » du projet.

A chaque changement de version pour une librairie tierce, je vérifie que le fonctionnement n’a pas changé. Si c’est le cas, il faudra mettre à jour mon code.

Téléchargement des mises à jour

 

Dans un terminal, je me place à la racine du site et j’exécute la commande qui peut faire peur :

$ php composer.phar update

Et oui, cette commande va chercher à mettre à jour toutes les librairies. L’exécution est longue et lorsque le téléchargement commence, un soulagement se fait sentir. Aucun conflit n’a été trouvé; ça ne veut pas dire qu’il n’y aura pas d’erreur(s) lors de l’exécution.

Test des nouvelles librairies

 

Une fois les nouvelles versions téléchargées et installées, commence la phase de débug !

La première chose que je fais est de vider les caches en supprimant les dossiers présents dans le dossier app/cache (var/cache depuis Symfony 3). Puis, dans la console, j’exécute les commandes suivantes :

$ php app/console cache:warmup

$ php app/console cache:warmup –env=prod

 

Si aucune erreur n’est présente à ce moment-là, vous n’avez pas d’erreur au niveau des annotations.

Voici celle que j’ai eue :

@Assert\MaxLength(100) est remplacé par @Assert\Length(max=100)

 

Si vous utilisez le bundle JMS/SerializerBundle et si vous êtes passés de la version 1.x à la version 2.0, les annotations ont changé de place. Il faut donc changer toutes les instructions « use » de vos fichiers.

 

Maintenant que le kernel démarre, passons aux choses sérieuses.

 

Avez-vous écrit vos tests unitaires et fonctionnels ? Non, c’est une mauvaise idée mais il n’est pas trop tard pour le faire.

 

Pour détecter toutes les erreurs, je teste le logiciel dans les moindres détails. A chaque erreur rencontrée, je commence par écrire les tests unitaires et fonctionnels permettant de générer l’erreur. Le test échouera bien sûr mais sera concluant une fois la correction apportée.

 

Pourquoi perdre du temps à écrire des tests ? Et bien pour en gagner plus tard. Un test écrit pour un bug permet d’éviter son retour !

 

Car une fois que tous ces tests seront écrits, vous les exécuterez avant chaque livraison pour vérifier que tout fonctionne bien. Il n’est pas exclu qu’un bug passe au travers du filet.

 

Mise en production

 

Après quelques heures de travail, le logiciel fonctionne bien. Que reste-il à faire ?

Sauvegarder les corrections du code dans le gestionnaire de codes sources ainsi que les fichiers « composer.json » et « composer.lock ».

Ce dernier est le précieux sésame pour la mise en production. C’est grâce à lui et la commande suivante que l’installation se passera sans problème en production.

$ php composer.phar install –prefer-dist

 

Mon petit truc pour la mise en production : installer un nouveau site et une fois le nouveau site fonctionnel, réaliser la bascule. Ainsi, la coupure est limitée dans le temps.

D’autre part, j’évite de livrer de nouvelles fonctionnalités avec un changement de version du framework, surtout si elles modifient la base de données. Mais là chacun fait selon ses circonstances.

 

Bonne mise à jour ! Contactez moi si vous avez des difficultés !