Archives par étiquette : lib

GPIO – Servos moteurs, joypad et WiFi

IMG_5494

Nous allons voir dans cet article comment réaliser une station de pilotage à distance pour commander des servos moteurs, à l’aide d’un Raspberry Pi, d’un joypad et d’un lien WiFi. Dans cet exemple j’uitiliserai un eeePC 901 pour la station de pilotage, mais il est tout à fait possible d’utiliser un deuxième Raspberry Pi.

Voici un schéma global :

pi joystick servoLa construction de ce dispositif se fait en trois étapes :

  1. Contrôle des servos moteurs par le Pi
  2. Utilisation du joypad
  3. Envoi des commandes à distance par wifi

Liste du matériel utilisé dans cet article

 

1 – Contrôle des servos moteurs par le Pi

Pour piloter plusieurs servos moteurs avec un Pi, nous n’avons d’autre choix que de passer par une carte contrôleur. Le site Adafruit propose justement un circuit permettant de contrôler jusqu’à 16 servos moteurs en utilisant le bus I²C (disponible sur le GPIO du Pi comme expliqué dans cet article GPIO – Entrée en matière).

imageVous pouvez acheter ce circuit directement sur le site d’Adafruit : Adafruit 16-Channel 12-bit PWM/Servo Driver – I2C interface – PCA9685

imageVous devrez sortir votre fer et souder les broches sur le circuit imprimé 🙂 Un bornier est prévu pour connecter une source d’alimentation. J’utilise un bloc coupleur de pile avec 4 piles AA pour fournir une tension de 6V, parfait pour alimenter mes servos moteurs.

Côté servos, je dispose de deux gros FUTABA S3010 et d’un minuscule FUTABA S3114.

Le branchement de la carte sur le Pi peut se faire simplement à l’aide de wire jumpers. Il suffit de connecter l’alimentation (3,3V et la masse/ground) ainsi que les broches SCL et SDA comme sur le schéma ci-dessous :

branchement_16cUne fois les branchements effectués, il convient d’activer le support de l’I²C sur le Raspberry Pi. Ceci se fait en deux étapes :

1 – Editez le fichier /etc/modules et ajoutez les deux lignes suivantes :

i2c-bcm2708
i2c-dev

2 – Editez ensuite le fichier /etc/modprobe.d/raspi-blacklist.conf et commentez les deux lignes suivantes (en ajoutant # au début de ces deux lignes) :

# blacklist spi-bcm2708
# blacklist i2c-bcm2708

Pour finir, installez l’outil i2c-tools et redémarrez le Pi :

apt-get install i2c-tools
shutdown -r now

Pour vérifer que la carte est bien reconnue par le Pi, lancez la commande suivante :

i2cdetect -y 1 # pour la révision 2 du Pi

ou

i2cdetect -y 0 # pour la première version du Pi

Vous devriez obtenir ce résultat :

root@raspberrypi:~# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --

Bien ! Nous allons maintenant écrire le programme en Python qui va nous permettre de piloter ces servos moteurs. Python est installé par défaut sur Raspbian, il ne manque que certains paquets :

apt-get install python-dev python-rpi.gpio python-smbus

Adafruit propose une librairie Python qui permet de dialoguer facilement avec les différents composants distribués par son site. Nous n’allons pas nous en priver 🙂 Pour télécharger la dernière version disponible de cette librairie, il suffit d’en récupérer les sources sur le dépôt GIT :

git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git

La partie qui nous intéresse ici se trouve dans le répertoire Adafruit-Raspberry-Pi-Python-Code/Adafruit_PWM_Servo_Driver.

Dans un premier temps, voici un petit script qui permet de tester les servos test_servo.py :

#!/usr/bin/python

from Adafruit_PWM_Servo_Driver import PWM
import sys

pwm = PWM(0x40, debug=True)
pwm.setPWMFreq(60)

pwm.setPWM(int(sys.argv[1]), 0, int(sys.argv[2]))

Pensez à rendre ce script exécutable grâce à la commande chmod 755 test_servo.py

Ce script prend deux paramètres :

  • l’id du port contrôlant un servo de 0 à 15
  • une valeur, généralement entre 150 et 600 qui détermine la position que doit prendre le servo

Exemples pour commander le servo branché sur le premier port (ayant pour id 0) :

./test_servo.py 0 480
./test_servo.py 0 240

Et voilà, si tout s’est bien passé, vous devriez pouvoir piloter vos servos de cette manière. Nous verrons plus loin dans cet article comment les piloter avec un joypad et à distance 🙂

Note : Je ne sais absolument pas pourquoi le troisième paramètre de la fonction setPWM() doit être entre 150 et 600… De même, je ne sais pas à quoi correspond le deuxième paramètre attendu par cette fonction. Si quelqu’un connaît la réponse, merci de nous expliquer cela en commentaire de cet article 🙂

2 – Utilisation du joypad

26-127-505-02Je dispose d’un magnifique joypad USB, modèle Saitek P990 munis de deux mini-joysticks ou « chapeaux chinois ». Nous allons utiliser ces deux joysticks pour piloter nos servos.

Un joystick qu’est ce que c’est ? En fait, c’est simplement un potentiomètre dont la valeur (la résistance) est interprétée et traduite en nombre. Sur ce modèle de joypad, les valeurs sont échantillonnées de 0 à 1023 (soit 1024 valeurs possibles). Pour obtenir deux axes, il y a deux potentiomètres par joystick. Avec deux joysticks, nous avons donc de quoi piloter indépendamment 4 servos 🙂

La librairie Python evdev permet d’interagir facilement avec les événements déclenchés par des périphériques USB. Pour l’installer :

apt-get install python-pip python-dev
pip install evdev

Avant d’écrire un script Python qui sache interpréter les actions de ces joysticks, vous devez connaître l’identifiant « event » attribué par le système au moment où vous branchez votre joypad USB.

lsusb
Bus 001 Device 003: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 005: ID 05e3:0505 Genesys Logic, Inc.
Bus 002 Device 003: ID 06a3:040b Saitek PLC P990 Dual Analog Pad
Bus 005 Device 002: ID 0b05:b700 ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 006: ID 11b0:6148 ATECH FLASH TECHNOLOGY
Bus 001 Device 007: ID 05af:3062 Jing-Mold Enterprise Co., Ltd Cordless Keyboard
Bus 001 Device 008: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse

Mon joypad est bien reconnu par le système avec la dénomination : « Saitek PLC P990 Dual Analog Pad« .

cat /proc/bus/input/devices

Cherchez la référence à votre joypad et repérez l’identifiant « event », ici nous avons l’identifiant « event6« .

[...]

I: Bus=0003 Vendor=06a3 Product=040b Version=0100
N: Name="Saitek P990 Dual Analog Pad"
P: Phys=usb-0000:00:1d.0-2/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/input/input15
U: Uniq=
H: Handlers=event6 js0
B: PROP=0
B: EV=1b
B: KEY=3fff 0 0 0 0 0 0 0 0 0
B: ABS=30027
B: MSC=10

[...]

A chaque fois que l’on va presser un bouton sur le joypad, ou actionner un de ses joysticks, un événement sera déclenché. Il s’agit donc de surveiller en permanence les événements déclenchés et d’agir en fonction. Voici maintenant un petit script Python qui permet de tester votre joypad et d’identifier les différents événements liés à chaque joystick et chaque bouton : test_joypad.py

#!/usr/bin/python

from evdev import InputDevice, categorize, ecodes
from time import sleep
from datetime import date
import os, sys, socket

dev = InputDevice('/dev/input/event6') # reprendre le même identifiant "event"
print(dev)

for event in dev.read_loop(): # boucle qui surveille l'arrivée d'un événement
  e_code=event.code
  e_type=event.type
  e_value=event.value
  print(str(e_type)+' - '+str(e_code)+' - '+str(e_value))

A chaque fois que vous toucherez quelque chose sur votre joypad, ce script affichera trois variables, e_code, e_type et e_value :

./test_joystick.py
device /dev/input/event6, name "Saitek P990 Dual Analog Pad", phys "usb-0000:00:1d.0-2/input0"
3 - 0 - 508
3 - 0 - 412
3 - 0 - 347
3 - 0 - 391
3 - 0 - 457
3 - 0 - 511
3 - 1 - 602
3 - 1 - 701
3 - 1 - 771
3 - 1 - 659
3 - 1 - 561
3 - 1 - 511

Voilà ce que j’obtiens en actionnant le joystick gauche de mon joypad, identifié par l’e_code 3. Dans l’axes des X, j’obtiens un e_type 0, et un e_type 1 pour l’axe des Y. Lorsque je relâche le joystick en position centrale, les valeurs sont proches de 512 (valeur médiane entre 0 et 1023). Ces caractéristiques sont propres à ce modèle de joypad, mais le principe de fonctionnement est le même pour tous 🙂 Ce petit script vous permettra de noter l’e_code et l’e_type de chaque bouton et joystick que vous voulez utiliser.

Pour ma part, j’ai trois servos à piloter, et je dispose de deux joysticks avec chacun deux axes. J’utiliserai l’axe X du joystick gauche (e_code 3, e_type 0) pour piloter le servo 1. L’axe Y du joystick gauche (e_code 3, e_type 1) pour piloter le servo 2. Et enfin l’axe X joystick droit (e_code 3, e_type 5) pour piloter le servo 3 🙂

A partir de là, vous pouvez facilement imaginer associer le servo 1 au roulis d’un avion, le servo 2 au tangage et le servo 3 au lacet par exemple 🙂

La dernière étape consiste à envoyer les commandes du joypad, branché sur la station de pilotage, au Raspberry Pi qui répercutera les ordres sur ses servos 🙂

3 – Envoi des commandes à distance par wifi

Nous avons d’un côté un script Python qui tourne sur un Raspberry Pi qui a pour rôle de piloter des servos. De l’autre, nous avons un eeePC (ou autre machine…), qui exécute un second script Python dont le but est d’interpréter les commandes envoyées par un joypad. Il s’agit maintenant de faire communiquer ces deux scripts entre eux, ce que nous pouvons facilement faire grâce aux sockets 🙂

Sans trop rentrer dans les détails, il s’agit d’ouvrir une socket au niveau du script qui s’exécute sur le Pi afin qu’il soit à l’écoute de messages envoyés par le script côté « station de pilotage ». Le script côté « station de pilotage » se connecte à cette socket en passant par le réseau IP (via WiFi), et envoie les commandes déclenchées par le joypad.

Côté Raspberry Pi :

#!/usr/bin/python

from Adafruit_PWM_Servo_Driver import PWM
import sys, os, socket

listen_address = ('0.0.0.0', 12800) # écoute sur toutes les interface sur le port 12800

srv_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # protocole UDP
srv_socket.bind(listen_address)
print "server enabled"

pwm = PWM(0x40, debug=True) # initialisation de la carte contrôleur
pwm.setPWMFreq(60)

while True:
  query, clt_address = srv_socket.recvfrom(1024) # écoute les message
  order=query.split('_') # on découpe les messages reçus
  servo=order[0]
  pos=order[1]
  print str(query)+' - '+str(servo)+' - '+str(pos) # on affiche les infos
  pwm.setPWM(int(servo), 0, int(pos)) # on envoie la commande au servo
sys.exit(0)

Côté Station de pilotage :

#!/usr/bin/python

from evdev import InputDevice, categorize, ecodes
from time import sleep
from datetime import date
import os, sys, socket

now = date.today()
print(now)

clt_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # protocole UDP
srv_address = ('192.168.101.27', 12800) # on vise l'adresse IP du Pi sur le port 12800

dev = InputDevice('/dev/input/event6') # initialisation du joypad
print(dev)

def convertAxis (value, axis_max): # fonction qui convertie les valeurs des joystick
  facteur=axis_max/490
  new_value=int(round((value/facteur)+150, 0))
  return new_value

for event in dev.read_loop(): # pour chaque événement détecté
  e_code=event.code
  e_type=event.type
  e_value=event.value
  print(str(e_type)+' - '+str(e_code)+' - '+str(e_value))
  if e_type == 3:
    if e_code == 0: # à destination du servo 1
      servo_pos=str(convertAxis (e_value, 1024))
      clt_socket.sendto("0_"+servo_pos, srv_address)
    elif e_code == 1: # à destination du servo 2
      servo_pos=str(convertAxis (e_value, 1024))
      clt_socket.sendto("1_"+servo_pos, srv_address)
    elif e_code == 5: # à destination du servo 3
      servo_pos=str(convertAxis (e_value, 512))
      clt_socket.sendto("2_"+servo_pos, srv_address)

Conclusions

En déclinant ce principe, vous pouvez piloter de nombreux servos moteurs à distance et commencer à envisager la construction systèmes complexes comme des robots ou des drones 🙂

En parlant de drone, ces articles relatifs au GPIO me serviront à construire un drone avion, comme expliqué ici : Raspberry Pi BOA Drone 🙂

Cependant, certaines zones d’ombre persistes, notamment sur le pilotage de servos. L’utilisation de la lib distribuée par Adafruit évite de se poser de question, cela fonctionne immédiatement. La contre partie, c’est qu’on ne comprend pas forcément tout ce qui se passe. Aussi, j’invite les lecteurs de ce blog à intervenir en commentaire de cet article afin d’apporter des informations complémentaires, des idées ou simplement des remarques 🙂

Merci à vous 🙂

9 – Module 6 – Graphique de la bande passante

Pour diverses raisons, il peut intéressant de s’avoir si notre bande passante internet est saturée ou non. Ce module affiche un historique d’environ 5 minutes de l’utilisation de la bande passante descendante (download) et montante (upload). De cette manière, je peux voir en un seul coup d’oeil si quelque chose d’anormal se passe sur mon réseau.

jarvis_screenshot_ifstat

Introduction

Ce module est de loin le plus compliqué de tous. D’une part, il va falloir récupérer le débit instantané utilisé par l’interface réseau de la gateway qui est reliée à la Box internet. Puis, il va falloir transmettre ces données au Pi sur lequel fonctionne le dashscreen. Enfin, il faudra créer un graphique pour représenter ces informations…

En effet, j’ai choisi de ne pas utiliser de soft type mrtg qui sont spécialisés pour ce genre de chose. Je préfère installer le minimum de soft, et utiliser quelques commandes de base. Pour faire quelque chose de simple (comme afficher la bande passante sur la graphique), pas besoin de sortir l’artillerie lourde 🙂 Et puis …si on ne se compliquait pas la vie, ce serait beaucoup moins drôle, n’est ce pas ? 😉

Mesurer la bande passante

ifstat est un petit outil en ligne de commande qui affiche les statistiques d’utilisation d’une interface réseau. Dans un terminal, taper la commande suivante :

ifstat -n -i eth0

Et vous obtiendrait en continue, quelque chose dans le genre :

       eth0       
 KB/s in  KB/s out
    0.45      0.06
    0.71      0.39
    2.85      0.76
    0.57      0.06
    1.86      0.19
    0.45      0.06
    0.45      0.06
    0.45      0.06
    0.57      0.06
    0.59      0.13
    0.45      0.06
    0.45      0.06
    0.59      0.26
    0.57      0.06
    1.74      0.13
    ...

Chaque seconde on obtient le débit instantané (ou presque), en KBytes/s, c’est à dire en Ko/s 🙂 C’est exactement ce qu’il nous faut 🙂 Il convient maintenant d’envoyer ces informations en continue sur notre Pi.

Transmettre les données au Pi à travers le réseau

Le moyen le plus simple de transmettre une info d’un ordinateur à un autre c’est de les envoyer dans des paquets UDP… C’est tellement trivial qu’il ma fallu plusieurs jours avant d’en avoir l’idée !

La commande netcat est tout à fait appropriée pour ce type d’opération. Sur une machine A qui joue le rôle de serveur faites :

nc -u -l 12345
  • -u : pour utiliser l’UDP
  • -l : pour passer en mode écoute (serveur)
  • 12345 : un numéro de port découte

Puis sur une machine B qui joue le rôle de client, faites :

nc -p 8888 -u 10.0.0.1 12345
  • -p 8888 : un port source
  • -u : pour utiliser l’UDP
  • 10.0.0.1 : adresse IP de la machine A (serveur)
  • 12345 : port d’écoute de la machine A (serveur)

Et hop, tout ce que vous tapez au clavier sur B, s’affiche sur A 🙂

Albert Einstein disait « Tout devrait être rendu aussi simple que possible, mais pas plus ! ».

A méditer 😉

Pour transmettre les données renvoyées par la commande ifstat à travers netcat, nous utiliserons un pipe. Voici les deux scripts complets (client/serveur) pour réaliser cette opération :

  • Script serveur à exécuter sur le Pi nc_ifstat_srv.sh :
### BEGIN INIT INFO 
# Provides: nc_ifstat_srv 
# Required-Start: 
# Required-Stop: 
# Default-Start: 2 3 4 5 
# Default-Stop: 0 1 6 
# Short-Description: ifstat for Jarvis 
# Description: Enable service provided by daemon. 
### END INIT INFO

dst_port=12345
dst_dir=/home/jarvis/ifstat
dst_file=eth0.log

nc -u -l $dst_port >> $dst_dir/$dst_file&
  • Script client à exécuter sur votre gateway/routeur nc_ifstat_clt.sh  :
### BEGIN INIT INFO
# Provides:          nc_ifstat_clt
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ifstat for Jarvis
# Description:       Enable service provided by daemon.
### END INIT INFO

src_port=8888
dst_port=12345
dst_host=10.0.0.2
eth=eth0

nc_ifstat()
{
	while [ "true" ]
	do
  		ifstat -n -i $eth | nc -p $src_port -u $dst_host $dst_port
  		sleep 5
	done
}

case "$1" in
        stop)
		echo " Stoping ifstat for Jarvis..."
                killall ifstat
		killall nc
		;;
        start)
		echo " Starting ifstat for Jarvis..."
		nc_ifstat&
		exit 0	
                ;;
        *)
                exit 1
                ;;
esac

exit 0

Pour exécuter le script au démarrage de la machine, placer le dans le répertoire /etc/init.d puis lancer la commande :

update-rc.d nom_du_script.sh defaults

A ce stade, vous devriez avoir un fichier sur votre Pi dans lequel, chaque seconde, la bande passante instantanée y est ajoutée en fin de fichier 🙂 Il ne nous reste plus qu’à lire ce fichier avec un script PHP, et dessiner le graphique pour représenter les données qu’il contient 🙂

Création du graphique en PHP

Ici encore, j’aurais pu utiliser une lib graphique en PHP, en JavaScript ou en n’importe quoi d’autre. Mais au lieux de sous exploiter une usine à gaz difficilement personnalisable, j’ai préféré créer ma propre fonction graphique en PHP. Vous allez voir que c’est beaucoup plus simple que ce qu’on peut s’imaginer 🙂

Voici ma fonction imagickHisto() :

function imagickHisto ($max, $eth = '', $up_down = 'down') {

  $datas = parseData ("eth0.log", $up_down);

  $width            = 304; // largeur du graphique
  $height           = 100; // hauteur du graphique
  $padding          = 1;
  $ticks            = 5;
  $background_color = '#000'; // couleur du fond
  $axes_color       = '#555'; // couleur des axes

  if($up_down == 'down'){
    $data_color       = '#1D1'; // couleur du graphique pour le download
  }
  else{
    $data_color       = '#D11'; // couleur du graphique pour l'upload
  }

  $nb_values        = $width - 2*$padding - 2;
  $max_value        = $height - 2*$padding - 4;

  $nb_datas         = sizeof($datas);
  $trim             = $nb_values - $nb_datas;

  if($trim < 0){$trim = 0;}

  $image = new Imagick();
  $image ->newImage( $width, $height, new ImagickPixel($background_color) );
  $draw  = new ImagickDraw();
  $draw->setStrokeColor( new ImagickPixel($axes_color) );

  $xx1    = $padding;
  $xy1    = $height - $padding - 1;
  $xx2    = $width - $padding - 1;
  $xy2    = $xy1;
  $yx1    = $xx1;
  $yy1    = $xy1;
  $yx2    = $yx1;
  $yy2    = $padding;
  $half_y = $height/2;
  $half_x = $width/2;

  $draw->line  ( $xx1, $xy1, $xx2, $xy2 );
  $draw->line  ( $yx1, $yy1, $yx2, $yy2 );

  $draw->line  ( $yx1, $yy2, $yx1+$ticks, $yy2 );
  $draw->line  ( $yx1, $half_y, $yx1+$ticks, $half_y );

  $draw->setStrokeColor( new ImagickPixel($data_color) );

  $first_x = $xx1 + 1 + $trim;
  $last_x  = $xx2 - 1;
  $first_y = $xy1 - 1;
  $last_y  = $yy2 + 1;

  for($i=0;$i<$nb_values;$i++){
    if(isset($datas[$i])){
      $value   = $datas[$i]*$max_value/$max;
      $value_y = $first_y - $value;
      $value_x = $first_x + $i;
      $draw->line  ( $value_x, $first_y, $value_x, $value_y );
    }
  }

  $image->drawImage( $draw );

  $text_draw = new ImagickDraw();
  $text_draw->setFillColor($axes_color);
  $text_draw->setFontSize( 12 );
  $image->annotateImage($text_draw, $half_x-20, $padding+10, 0, "$eth - $up_down");

  $image->setImageFormat( "png" );
  header( "Content-Type: image/png" );
  echo $image;
  exit;
}

Veuillez accepter mes excuses pour le manque cruel de commentaire dont fait l’objet cette fonction. Pour résumer, la fonction prend trois paramètres :

  • $max : la valeur max (en Ko) pour borner le graphique. Par exemple, mon débit réel maximum atteint 1800 Ko/s. Je choisie donc $max = 2000.
  • $eth : nom de l’interface (exemple eth0)
  • $up_down : « up » ou « down » pour spécifier la couleur du graphique ainsi que les données à afficher issue de ifstat

La fonction lit un tableau de donnée renvoyé par la fonction parseData(), puis dessine sur le graphique une barre de 1px de large par donnée. Avec une largeur de 300px, on peut donc afficher 5 minutes d’historique de données 🙂

Voici la fonction parseData() dont le rôle est de lire le fichier contenant les données issues de la commande ifstat :

  function parseData ($stat_file, $up_down) {
    $datas = array();
    if(filemtime($stat_file) < time()-10){return $datas;}
    $stats = fopen($stat_file, 'r');
    while (($line = fgets($stats)) !== false) {
      $explode_line = str_word_count($line, 1, "0123456789.");
      if($up_down == 'down') {
        $datas[]  = $explode_line[0];
      }
      else{
        $datas[]  = $explode_line[1];
      }
    }
    fclose($stats);
    $datas = array_slice($datas, -300);
    return $datas;
  }

Cette fonction prend deux paramètres :

  • $stat_file : fichier à parser
  • $up_down : « up » ou « down » pour distinguer les données d’upload et de download

Pour la suite, nous reprennons la même démarche que pour les autres modules 🙂

index.php

Il faut une div par graphique ; nous en ajoutons donc deux au fichier index.php, une pour l’upload et une pour le download.

 <div id="ifstat_eth0_up"><img id="img_eth0_up" src="pict/blank.png"></div>
 <div id="ifstat_eth0_down"><img id="img_eth0_down" src="pict/blank.png"></div>

Comme pour le module Xplanet, il convient d’initier la source des balises images <img> avec une image vide blank.png.

style.css

Il suffit ici de positionner nos deux <div> :

/* ifstat */

div#ifstat_oberon_up
{
  right             : 20px;
  bottom            : 20px;
  position          : absolute;
  overflow          : hidden;
  background-color  : rgba(0, 0, 0, 1);
}

div#ifstat_oberon_down
{
  right             : 340px;
  bottom            : 20px;
  position          : absolute;
  overflow          : hidden;
  background-color  : rgba(0, 0, 0, 1);
}

javascript.js

Une simple requête AJAX permet de récupérer les graphiques à afficher.

/* ifstat */

var ifstat_timeout;

function ifstat () {

  var now             = new Date().getTime();

  var url_down = "ajax.php?block=ifstat&eth=wan&up_down=down&max=2000&hour="+now;
  var img_eth0_down = $("<img />").attr("src", url_eth0_down);
  $("#img_eth0_down").attr("src", url_eth0_down);

  var url_up   = "ajax.php?block=ifstat&eth=wan&up_down=up&max=150&hour="+now;
  var img_eth0_up = $("<img />").attr("src", url_eth0_up);
  $("#img_eth0_up").attr("src", url_eth0_up);

  ifstat_timeout = setTimeout("ifstat()", 5000);
}

Même principe que pour le module Xplanet, il convient de précharger les images avant de les afficher. Je fixe le délais de rafraichissement à 5 secondes, ce qui est suffisant.

ajax.php

Le code à ajouter dans ce fichier reste élémentaire comme pour les autres modules. Il ne faut toutefois pas oublier de prendre en compte les paramètres de la fonction imagickHisto() :

  /////////////////////////////////////////////////
  //  IFSTAT
  /////////////////////////////////////////////////

  if($block == 'ifstat'){
    imagickHisto ($_REQUEST['max'], $_REQUEST['eth'], $_REQUEST['up_down']);
  }


inc.php

Dans ce fichier, il suffit de copier-coller les fonctions imagickHisto() et parseData() qui ont été décrites plus haut dans cet article.

Voilà le rendu final en gros plan, lorsque la bande passante est très sollicitée :

ifstat