Script de création d’un daemon sous Debian

Pour la station météo, certains programmes doivent fonctionner en tache de fond. Pour cela on utilise des démons.

Dans mon exemple j’ai un script Python à lancer. Ce script est capable de fonctionner en mode autonome mais je souhaite l’intégrer au système. Mon service s’appelle « launcher ».

#!/bin/sh

### BEGIN INIT INFO
# Provides:          launcher
# Required-Start:    $remote_fs
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Run weathergh
# Description:       Run weatherg-hardware as daemon.
### END INIT INFO

. /lib/lsb/init-functions

[ -f /etc/default/rcS ] && . /etc/default/rcS
PATH=/bin:/usr/bin:/sbin:/usr/sbin

SCRIPT_DIR=/home/rep/
SCRIPT=script_a_lancer.py

case "$1" in
  start)
    log_begin_msg "Running launcher"
    cd $SCRIPT_DIR
    python $SCRIPT --daemon
    log_end_msg 0
    ;;
  stop)
    log_begin_msg "Stopping launcher"

    cd $SCRIPT_DIR
    python $SCRIPT --quit
    log_end_msg 0
    ;;
  force-reload|restart)
    $0 stop
    $0 start
    ;;
  status)
    exit 0
    ;;
  *)
    log_success_msg "Usage: /etc/init.d/launcher {start|stop|restart|force-reload|status}"
    exit 1
esac

exit 0

Copier le script launcher dans le répertoire /etc/init.d/ et donner les droits d’exécution chmod +x /etc/init.d/launcher

Enregistrer le service et le démarrer :

update-rc.d launcher defaults
services start launcher

Sources :

https://openclassrooms.com/courses/faire-un-demon-sous-linux

Configuration du Raspberry Pi en mode « kiosk screen » pour la station météo

La station météo a vocation à être posée sur un meuble. Donc souhaite afficher en plein écran les informations importantes. De manière transparente on ne souhaite pas montrer qu’il s’agit d’un ordinateur.

Faire de la place

J’ai décidé de supprimer quelques programmes dont je n’ai pas usage pour libérer un peu la carte SD. Entre autres : Minecraft ou LibreOffice, Sonic, etc…

D’abord une mise à jour :

sudo apt-get update && sudo apt-get upgrade -y

Puis on supprime les programmes inutiles :

sudo apt-get autoremove --purge wolfram-engine minecraft-pi sonic-pi libreoffice*

Enfin le ménage :

sudo apt-get clean

Installation

Ensuite nous avons besoin de Chromium et de quelques outils que l’on installe

sudo apt-get install chromium x11-xserver-utils unclutter

Nous allons utiliser Chromium en mode kiosque c’est à dire en plein écran, sans barre d’outils ni décoration de fenêtre.

Edit : Pour installer Chromium sur Jessie

wget -qO - http://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add -
echo "deb http://dl.bintray.com/kusti8/chromium-rpi jessie main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install chromium-browser rpi-youtube -y

Configuration

Nous allons indiquer à LXDE qu’il faut lancer Chromium automatiquement au démarrage. Editer le fichier /etc/xdg/lxsession/LXDE/autostart

# Commenter la ligne suivante afin désactiver l'écran de veille
#@xscreensaver -no-splash

# Les lignes suivantes désactivent la gestion de l'énergie. Elles empêchent l'écran de s'éteindre. 
@xset s off
@xset -dpms
@xset s noblank


# Cette ligne permet d'éviter d'afficher les messages d'erreur éventuels au démarrage
@sed -i 's/"exited_cleanly": false/"exited_cleanly": true/' ~/.config/chromium/Default/Preferences

# On indique à Chromium qu'il doit démarrer et sur quelle page il doit fonctionner 
@chromium --noerrdialogs --kiosk http://www.page-to.display

# --incognito Rajouter cette option si vous souhaitez démarrer en mode privée 

Et voici ! Il ne reste plus qu’à relancer la bête framboise !

Sources

https://www.danpurdy.co.uk/web-development/raspberry-pi-kiosk-screen-tutorial/

https://www.raspberrypi.org/forums/viewtopic.php?t=121195

Weatherg : Lecture des capteurs DHT22 et BMP185 en Python

Installer les dépendances :

Pour le DHT22, cloner la bibliothèque fourni par Adafruit et installer là :

$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
$ cd Adafuit_Python_DHT && sudo python setup.py install

Pour tester l’installation et votre câblage :

sudo examples/Adafruit_DHT 22 4

Ici 22  correspond au DHT22, pour le DHT11, utiliser 11 . Le 4 correspond à la broche GPIO #4 du Raspberry PI.

Recommencer pour le BMP185, ce dernier est câblé sur les broche I2C.

$ git clone https://github.com/adafruit/Adafruit_Python_BMP.git
$ cd Adafruit_Python_BMP && sudo python setup.py install

Enfin un petit test :

sudo examples/simpletest.py
Exemple de code
# Adafruit library
import Adafruit_DHT
import Adafruit_BMP.BMP085 as BMP085

# sensor config
DHT_SENSOR = 22
PIN = 4

# Try to grab a sensor reading.  Use the read_retry method which will retry up
# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
# humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, PIN)
#
#
# Default constructor will pick a default I2C bus.
#
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
# from the main GPIO header and the library will figure out the bus number based
# on the Pi's revision.
#
# For the Beaglebone Black the library will assume bus 1 by default, which is
# exposed with SCL = P9_19 and SDA = P9_20.
#
# Can enable debug output by uncommenting:
#import logging
#logging.basicConfig(level=logging.DEBUG)
bmp_sensor = BMP085.BMP085()

# Optionally you can override the bus number:
#sensor = BMP085.BMP085(busnum=2)

# You can also optionally change the BMP085 mode to one of BMP085_ULTRALOWPOWER,
# BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES.  See the BMP085
# datasheet for more details on the meanings of each mode (accuracy and power
# consumption are primarily the differences).  The default mode is STANDARD.
sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)

bmp_temp = bmp_sensor.read_temperature()
bmp_pressure = bmp_sensor.read_pressure()
bmp_altitude = bmp_sensor.read_altitude()
bmp_sealevel_pressure = bmp_sensor.read_sealevel_pressure()

print 'BMP measures'
print 'Temp = {0:0.2f} *C'.format(bmp_temp)
print 'Pressure = {0:0.2f} Pa'.format(bmp_pressure)
print 'Altitude = {0:0.2f} m'.format(bmp_altitude)
print 'Sealevel Pressure = {0:0.2f} Pa'.format(bmp_sealevel_pressure)


print 'DHT ' + str(DHT_SENSOR) + ' measures'
if humidity is not None and temperature is not None:
    print 'Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity)
else:
    print 'Failed to get reading. Try again!'
    sys.exit(1)

Sources :

A venir

Carte de la station météo WeatherG

weatherg_card

Voici la première carte WeatherG que je viens de recevoir. Celle-ci permet les relevés de températures, pression et humidité grâce aux DHT22 et BMP180.

J’ai conçu la carte afin de pouvoir l’emboiter, avec le connecteur J1, avec d’autres cartes maison. Le connecteur J2 est utile pour alimenter l’écran du PI.

Voici mon fichier source Fritzing : a venir

Je suis passé par le FritzFab pour la réalisation. A ce sujet, je trouve la qualité de fabrication très intéressante. Les délais sont très corrects. Le prix relativement abordable. Par contre gros bémol sur les frais de port, 15€ pour une lettre d’Allemagne, dommage qu’il n’y pas d’autres options qu’UPS. J’en ai eu pour un total de 48€.

ng-pluralize et les nombres négatifs

Dans le cadre du développement du front-end de la station météo, je suis confronté à l’affichage des minutes d’ensoleillement gagnées ou perdues.

Pour cela, j’utilise la directive ng-pluralize  d’Angular :

<ng-pluralize count="main.suntimeDiff"
              when="main.suntimeDiff >=0 ? main.sunTimeLabel : main.negSunTimeLabel" >
</ng-pluralize>
    vm.negSunTimeLabel = {
      'other': '{} minutes de soleil'
    };

    vm.sunTimeLabel = {
      '0': 'pas de minute de soleil gagnée ou perdue',
      'other': '+{} minutes de soleil'
    };

J’ai donc deux tableaux de labels en fonction de l’état de ma variable.

Projet : création d’une station météo à base de Raspberry Pi

J’ai décidé de me fabriquer une station météo à base de Rasberry Pi. Une série d’article détaillera suivant mon humeur, les étapes de cette station météo. Le projet est pour le moment à l’état d’ébauche. Cet article a pour but de servir de cahier des charges et de lister le matériel.

[toc]

Cahier des Charges
Informations disponibles

La station météo devra fournir les informations suivantes :

  • Température,
  • Humidité de la pièce,
  • Pression,
  • Qualité de l’air.

Dans un second temps, les informations complémentaires pourront être disponibles :

  • Température extérieure,
  • Pression extérieure,
  • Humidité extérieure,
  • Prise de vue du Jardin.

En somme, un capteur déporté devra pouvoir être installé. Ce capteur fonctionnera à l’énergie solaire. Le protocole de communication avec la station est encore à définir.

Fonctionnalités
  • Les informations devront être disponibles à distance (Web, API et frontend).
  • Les informations seront affichées sur un écran embarqué tactile.
  • Les informations seront enregistrées dans une base de données.
  • Les informations seront conservées pour une durée de 3 mois.
  • Une synthèse journalière sera générée pour archive. Il sera possible d’afficher cette synthèse pour chaque journée et d’afficher des courbes de comparaison.
  • Il devra être possible d’éteindre l’écran pour limité la consommation d’énergie.
Matériel
  • Rasberry Pi 2 model B, chez LDLC (45€)
  • Carte Mémoire Sandisk 16Go, chez LDLC (9€)
Capteurs
  • Humidité/Température : DHT22, chez Adafruit (10$)
  • Pression/Température : BMP085, chez Adafruit (20$)
  • Pression/Température: BMP180, chez Adafruit (10$)
Périphériques
  • Écran 7″ tactile, chez Adafruit (80$), chez Swag (58£), RS (60 €)
  • Boitier Pour l’écran, chez Adafruit (15$), KUBII (12.50 €)
  • Alimentation USB 2A, chez Swag (5£), RS (5 €)
  • Module Wifi USB, chez Adafruit (20$)
Composants Divers
  • 1x Résistance 10KOhms, chez Adafruit (0.75$ les 25)
  • 1x Fiche 40 pins, Adafruit (0.75$)
Matériel de mise au point
  • Carte d’essais, chez Adafruit (6$)
  • Cobbler 40 pins, chez Adafruit (6.50$)
Étapes de fabrication
  1. Élaboration du cahier des charge et conception
  2. Commande du matériel chez les différents fournisseurs
  3. Prototypage sur une carte d’essais du modèle simple (sans module déporté)
  4. Réalisation d’un circuit imprimé et commande chez un professionnel.
  5. Mise en place du premier modèle
Ressources

 

Mises à jour
  • 27/01/2016 : Commande Adafruit
  • 03/02/2016 : Commande RS
Matomo encountered an error: Uncaught Error: Class "Piwik\Plugins\CustomVariables\CustomVariables" not found in /var/www/piwik/core/Tracker/TrackerCodeGenerator.php:98 Stack trace: #0 /var/www/piwik/plugins/SitesManager/API.php(159): Piwik\Tracker\TrackerCodeGenerator->generate() #1 [internal function]: Piwik\Plugins\SitesManager\API->getJavascriptTag() #2 /var/www/piwik/core/API/Proxy.php(255): call_user_func_array() #3 /var/www/piwik/core/Context.php(28): Piwik\API\Proxy->Piwik\API\{closure}() #4 /var/www/piwik/core/API/Proxy.php(158): Piwik\Context::executeWithQueryParameters() #5 /var/www/piwik/core/API/Request.php(272): Piwik\API\Proxy->call() #6 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(46): Piwik\API\Request->process() #7 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(18): WP_Piwik\Request\Php->call() #8 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request.php(63): WP_Piwik\Request\Php->request() #9 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1038): WP_Piwik\Request->perform() #10 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1205): WP_Piwik->request() #11 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/TrackingCode.php(16): WP_Piwik->updateTrackingCode() #12 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(296): WP_Piwik\TrackingCode->__construct() #13 /var/www/thegtricks/wp-includes/class-wp-hook.php(324): WP_Piwik->addJavascriptCode() #14 /var/www/thegtricks/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #15 /var/www/thegtricks/wp-includes/plugin.php(517): WP_Hook->do_action() #16 /var/www/thegtricks/wp-includes/general-template.php(3068): do_action() #17 /var/www/thegtricks/wp-content/themes/twentyfifteen-child/footer.php(45): wp_footer() #18 /var/www/thegtricks/wp-includes/template.php(790): require_once('...') #19 /var/www/thegtricks/wp-includes/template.php(725): load_template() #20 /var/www/thegtricks/wp-includes/general-template.php(92): locate_template() #21 /var/www/thegtricks/wp-content/themes/twentyfifteen/archive.php(68): get_footer() #22 /var/www/thegtricks/wp-includes/template-loader.php(106): include('...') #23 /var/www/thegtricks/wp-blog-header.php(19): require_once('...') #24 /var/www/thegtricks/index.php(17): require('...') #25 {main} thrown (which lead to: Session must be started before any output has been sent to the browser; output started in /var/www/thegtricks/wp-includes/script-loader.php/2925)