Dans cette page, j’explique tous les paramètres de configuration du Pi nécessaires à l’exécution du script de capture d’image. Le script de capture d’image est également décortiqué en fin de page.
Auto-login et exécution du script au démarrage
Une fois mis sous tension, le Pi boot immédiatement. L’objectif est que l’utilisateur root prenne tout de suite la main, exécute le script, et éteigne le Pi.
Note : Je vous imagine déjà convulser à l’idée de tout faire en tant que root, car « c’est pas propre, pas secure, mal, etc… ». Ma réponse est simple : Aucune importance ! Il n’y a là aucun enjeu de sécurité. L’utilisation du compte root me permet de réaliser toutes les opérations sur le sytème et d’accéder à tous les périphériques sans devoir configurer des droits particuliers ou gérer des élévations de privilèges.
Pour que l’utilisateur root soit automatiquement connecté au démarrage, il faut éditer le fichier /etc/inittab, et remplacer la ligne :
1:2345:respawn:/sbin/getty --noclear 38400 tty1
Par :
1:2345:respawn:/bin/login -f root tty1 </dev/tty1 >/dev/tty1 2>&1
Pour exécuter notre script timelapse.sh lorsque l’utilisateur root se connecte, il suffit d’ajouter le chemin vers le script dans le fichier /root/.bash_profile :
/root/timelapse.sh >> /root/timelapse.log
Le script timelapse.sh doit évidemment être exécutable. A noter également que je redirige toutes les sorties de ce script vers un fichier de log, afin d’avoir des traces en cas de problème.
Le script timelapse.sh
Ce script ne se limite pas tout à fait à prendre une photo grâce à la commande streamer. Voici toutes les commandes exécutées par ce script, avec les explications qui s’imposent.
#!/bin/bash
date >> /root/uptime.log
Après le shebang qui convient, j’enregistre la date dans un fichier uptime.log. Cela a uniquement pour but de pouvoir contrôler, à postériori, combien de temps le Pi à pu fonctionner sur batterie.
output_dir=/root/timelapse
heartbeat_dir=/root/heartbeat
flag=/root/timelapse.flag
Je définis ensuite deux répertoires et un fichier, dont les rôles sont les suivants :
- /root/timelapse : répertoire dans lequel seront stockées toutes les images prises.
- /root/heartbeat : répertoire dans lequel seront stockées les miniatures des images à envoyer au serveur de monitoring.
- /root/timelapse.flag : fichier contenant un compteur qui est incrémenté à chaque fois que le script est lancé. Lorsque le compteur arrive à 3, le script enverra une requète au serveur de monitoring, et réinitialisera le compteur à 0.
now=`date "+%F_%H-%M-%S"`
Initialisation de la variable now qui servira pour notament pour nommer les images capturer.
streamer -f ppm -s 1280x720 -t 10 -r 3 -o $output_dir"/timelapse_"$now"_00.ppm"
On rentre dans le vif du sujet avec la commande streamer. Explications des paramètres :
- -f ppm : définit le format de fichier des images capturées (format ppm non compressé)
- -s 1280×720 : définit la résolution des images capturées (1280 pixels de large sur 720 pixels de haut)
- -t 10 : le nombre d’image à capturer. Je prends 10 photos pour que la webcam est le temps d’adapter la luminosité et le focus
- -r 3 : fréquence des prises de vue. Je prends 3 images par secondes, juste milieux entre les capacités du Pi à traiter les images, et délais d’adaptation de la webcam à la luminosité et au focus
- -o $output_dir »/timelapse_ »$now »_00.ppm » : La destination et le nom des images capturées. A noter que le nom du fichier de sortie se termine par « _00 », ce qui permet à streamer d’incrémenter ce numéro pour chacune des 10 photos prises.
rm $output_dir/*_00.ppm
rm $output_dir/*_01.ppm
rm $output_dir/*_02.ppm
rm $output_dir/*_03.ppm
rm $output_dir/*_04.ppm
rm $output_dir/*_05.ppm
rm $output_dir/*_06.ppm
rm $output_dir/*_07.ppm
rm $output_dir/*_09.ppm
rm $output_dir/*_10.ppm
Je supprime ensuite toutes les images capturées, sauf la 8ème. Pour des raisons que j’ignore, parfois, streamer va commencer en numérotant les images à partir de 00, et parfois à partir de 01, c’est pourquoi je supprime également les images se terminant par 10.
if [ ! -f $flag ] ; then
echo "0" > $flag
fi
Je test ensuite la présence du fichier comptenant le compteur, que j’initialise à 0 dans le cas où il n’existerait pas.
nb_flag=`cat $flag`
new_nb_flag=$(($nb_flag+1))
echo "$new_nb_flag" > $flag
Je récupère la valeur actuelle du compteur, je l’incrémente et je remplace la nouvelle valeur du compteur dans le fichier timelapse.flag. Lors de la première exécution du script, la valeur du compteur est donc logiquement égale à 1.
if [ "$new_nb_flag" == "1" ] ; then
echo " flag $new_nb_flag should send heartbeat now ... "
wvdial free&
img_origin=$output_dir"/timelapse_"$now"_08.ppm"
img_heartbeat=$heartbeat_dir"/timelapse_"$now"_08.jpg"
convert -compress jpeg -resize 25% $img_origin $img_heartbeat
curl --progress-bar --form img=@$img_heartbeat --form token=beat_B3O7A8S4 http://pi_timelapse/heartbeat_X8E7Q2L7.php
echo "heartbeat send ..."
Si la valeur du compteur est égale à 1, alors j’envoie un « battement de coeur » au serveur de monitoring. Pour cela, il faut établir une connexion 3G, ce qui est fait grâce à la commande wvdial free&. Afin de limiter au maximum la taille de l’image envoyée, je créé une miniature de la dernière image capturée (notez qu’il s’agit bien de la numéro 08) grâce à la commande convert offerte par le soft imagemagick.
Explication des arguments passés à la commande convert :
- -compress jpeg : Nous partons du format ppm non compressé, et nous souhaitons obtenir une image compressée en jpeg.
- -resize 25% : Pas besoin d’une image en haute définition, 25% de la taille d’origine suffit.
Nous obtenons une image qui pèse environ 12Ko, ce qui passe très bien par le dongle 3G, et qui me permettra de rester dans les 20Mo de data du forfait Free à 2€ 🙂
Enfin, j’utilise curl pour envoyer une requète au serveur de monitoring avec l’image miniature.
Explication des arguements passés à la commande curl :
- –progress-bar : permet d’afficher la barre de progression de l’envoie de l’image
- –form img=@$img_heartbeat : définit le champ « img » qui contient l’image à envoyer
- –form token=XXXXXXXXXXX : définit le champ « token », qui est en quelque sorte un mot de passe, pour éviter d’avoir de mauvaises surprises 😉
- http://pi_timelapse/heartbeat_XXXXXXXXX.php : Adresse du serveur de monitoring, et nom du script qui traite la requête. Les XXXXXXXX, sont là pour masquer le nom réel du script, toujours dans le but d’éviter les mauvaises surprises 🙂 Le nom de domaine pi_timelapse est résolu localement via le fichier /etc/hosts 😉
Continuons :
else
echo " flag $new_nb_flag no heartbeat ... "
if [ "$new_nb_flag" -gt "2" ] ; then
echo "reset flag"
echo "0" > $flag
fi
fi
Sinon (si le compteur n’est pas égal à 1), et qu’il est supérieur à 2, alors je réinitialise le compteur à 0. De cette manière, le « battement de coeur » n’est envoyé qu’une fois sur trois, soit toutes les 1/2 heure environ. La valeur du compteur étant initialisée à 0 au départ, le premier battement de coeur est envoyer dès la première mise sous tension, ce qui me permettra de m’assurer que tout fonctionne bien lorsque j’activerai le dispositif sur le terrain 🙂
if [ -f /root/shutdown.flag ] ; then
echo "shutdown flag detected ... shuting down !"
shutdown -h now
fi
Pour finir, j’éteint le Pi grâce à la commande shutdown. Notez que je vérifie la présence d’un fichier /root/shutdown.flag avant de lancer l’exctinction. Ceci me permettra de débrailler le système, en supprimant ce fichier j’empêcherai le système de s’éteindre et je pourrai prendre la main dessus.