Archives par étiquette : monitoring

1 – Raspberry Pi Home Dash Screen

J’ai toujours été passionné par la domotique et par tout ce qui touche à l’informatique dans la maison. J’adore les stations météo qui affichent tout un tas d’informations, les horloges high-tech qui font calendrier et qui sonnent quand vous recevez un mail, les cadres photos numériques, etc,… En revanche, vous ne trouverez chez moi aucun de ces appareils (ou presque). En effet, je trouve que ce qui existe aujourd’hui est soit beaucoup trop limités, soit très limités et beaucoup trop chers 😀

En parallèle, j’aime avoir une vue globale sur ce qui se passe sur mon réseau informatique à la maison. Savoir comment se porte ma bande passante, connaitre l’état de mes serveurs et NAS, savoir qui est connecté sur mon serveur TeamSpeak ou sur mon VPN, etc…

J’adore également savoir quelle est la phase de la lune, et connaître l’ensoleillement de la terre au cours de la journée, l’heure du lever et du coucher du soleil… Les écrans de contrôle de la NASA, comme on les voit dans les films, me font un certain effet 😉

Donc voilà, un projet relativement simple mais très fun, un écran tableau de bord pour regrouper toutes ces données 🙂

Bien en vue au dessus du bar qui sépare ma cuisine de mon séjour, voici ce que ça donne :

IMG_5393

Cette photo montre la chose dans sa version finale, proprement installée au mur.

En détail

Voilà la liste des informations qui sont représentées sur cet écran :

  • Phase de la terre avec cartographie des nuages en temps réel
  • Phase de la lune
  • Heure
  • Date
  • Météo du jour
  • Prévisions météo à 3 jours
  • Etat des serveurs et NAS
  • Clients TeamSpeak connectés
  • Clients VPN connectés
  • Bande passante internet

J’ajoute de temps en temps des fonctionnalités, tant qu’il reste de la place pour afficher des informations. L’important c’est que ce soit visible/lisible depuis n’importe où dans la pièce.

Voici ce que ça donne en détail (cliquez pour agrandir) :

dashscreen_final

Le matériel nécessaire

Contrairement à mes autres projets, ici un Raspberry Pi et un écran suffisent… D’ailleurs, vous pouvez utiliser autre chose qu’un Pi, notamment un vieux eeePC ou PC portable pour rester dans le compacte 🙂 Une tour standard fera également l’affaire si vous pouvez la planquer. J’ai simplement ajouté un dongle WiFi pour connecter le Pi au réseau car aucune prise RJ45 n’arrive à cet endroit. Un support mural pour accrocher l’écran au mur ainsi qu’une goulotte extra plate pour masquer les câbles d’alimentation. Si vous choisissez de poser votre écran au dessus de votre frigo par exemple, vous économiserez l’achat de ces deux accessoires.

Pour l’écran, choisissez le moins cher. Préférez les écrans LED, plus fin et qui consomment moins. Ils offrent généralement un angle de vue plus large (pratique quand on se balade dans la pièce), ainsi qu’une luminosité plus élevée. Si vous souhaitez l’accrocher au mur, il doit biensur disposer des fixations de type VESA. Pour la taille, c’est comme vous voulez, et cela dépend de ce que vous voulez afficher. Sachez toutefois qu’un écran de plus de 20-22″ devient vite encombrant… Je vous conseille donc une écran entre 16″ et 20″, au format 16/9 (plus esthétique qu’un 4/3), avec un bord fin (toujours par souci d’esthétisme 😉 ).

Voici en détail ce que j’ai choisi :

  • Un Raspberry Pi Modèle B 512Mo
  • Une carte mémoire SDHC 8Go
  • Un dongle WiFi USB NetGear WNA1000M
  • Un écran LCD AOC e941Vwa 18,5″ (n’importe quel écran peut convenir)
  • Un support mural VESA pour écranAavara EL1010
  • Une goulotte plate pour cacher les câbles

Dans les prochains articles, j’expliquerai comment procéder pour créer facilement ce type d’écran et je publierai tout mon code source en détaillant le fonctionnement de chaque module.

Comme toujours, et j’insiste, je compte sur vous pour alimenter la chose, partager vos avis et idées d’amélioration. Si vous réalisez quelque chose de ce type, ce pourrait être génial de créer un soft avec une bibliothèque qui regrouperait tous les modules créés. 🙂

IMG_5389

10 – Le serveur de monitoring

Au départ je souhaitais pouvoir prendre la main à distance sur le Pi pour m’assurer que tout fonctionne bien durant la semaine. Cependant, les contraintes d’autonomie du Pi sur batterie me forçant à ne temporiser sont fonctionnement 2 minutes toutes les 10 minutes, la fenêtre de tir pour choper le Pi lorsqu’il est up est franchement serrée.

Sans compter sur l’autonomie, je ne pourrai pas surveiller le Pi à longueur de journée pour voir si tout fonctionne bien, que rien ne gêne les prises de vue, etc,… Il faut donc que le Pi se manifeste tout seul, régulièrement : c’est le principe du « battement de coeur ». Le Pi envoi de lui même des battements de coeur réguliers, et si les battements de coeur s’arrêtent, c’est que quelque chose à mal tourné.

L’idée est donc d’utiliser un serveur distant, qui accusera réception de ces battements de coeur, et m’enverra un mail pour me dire que tout va bien. Chaque battement de coeur sera accompagné d’une miniature de la dernière photo prise. Tout est enregistré dans une base de données, et j’ai prévu une page qui récapitule toutes les battements de coeur enregistrés avec leur photo miniature. Ce qui me permettra également d’avoir un aperçu des travaux en direct.

Inutile d’envoyer un battement de coeur à chaque prise de vue. Un mail toutes les 10 minutes, c’est trop. Deux mails par heure, c’est mieux 🙂

Serveur web – Apache

Très concrètement, le serveur de monitoring est un simple serveur web Apache, accompagné d’une base de données MySQL et de quelques scripts PHP.

Je ne détail pas ici l’installation et la configuration de ces composants. C’est un sujet bien à part qui mériterait un chapitre complet. Si vous voulez faire pareil, vous pouvez utiliser un hébergement mutualisé chez Free ou OVH (les ftp Free mis à disposition des Freenautes font également parfaitement l’affaire).

Base de données

Je n’ai besoin que d’une seule table pour enregistrer chaque battement de coeur ainsi que la photo associée. Voici le schéma de la table heartbeat que j’utilise :

CREATE TABLE `heartbeat` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date` int(11) NOT NULL,
  `log` text COLLATE utf8_bin NOT NULL,
  `img` text COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

Description des champs :

  • id : un simple indexe auto incrémenté
  • date : champ entier pour stocker la date du battement de coeur sous la forme d’un timestamp
  • log : champt text permettant d’enregistrer des infos diverses
  • img : champ text contenant le nom de la miniature de la photo associée au battement de coeur

Fonctions et fichier de configuration

J’ai rassembler les fonctions génériques que j’utilise dans le fichier func.php que vous pouvez télécharger ici : func.php.tar.gz

L’ensemble des paramètres de configuration des scripts PHP sont rassemblés dans le fichier conf.php que vous pouvez télécharger ici : conf.php.tar.gz

Script PHP heartbeat.php

C’est ce script qui va être appelé par la commande curl comme expliqué dans le chapitre précédent. Sont rôle est de réceptionner la photo miniature, d’enregistrer la date de réception, et d’envoyer un mail.

Je vais à l’essentiel, le code de ce script est donc très minimaliste :

<?php

header('Content-type: text/html; charset=utf-8');

// inclusion des fichiers requis
require_once('conf.php');
require_once('func.php');

// initialisation de la session
$session_id = sessionStart();
// connexion à la base de données
$db_connect = dbConnect();
// nettoie la variable $_REQUEST
$_REQUEST   = clearRequest ($_REQUEST);

// enregistre la tentative de connexion dans un fichier de log
logIt('access', 'heartbeat connection ...');

// vérifie que le token donné correspond à celui attendu ;)
if(!empty($_REQUEST['token']) && $_REQUEST['token'] == $conf['token']['heartbeat']) {

  // si le fichier est bien réceptionné
  if (is_uploaded_file($_FILES['img']['tmp_name'])) {
    if (move_uploaded_file($_FILES['img']['tmp_name'], $conf['upload_dir'].'/'.$_FILES['img']['name'])) {

      $field_data = array (
                              'date'  => time(),
                              'img'   => $_FILES['img']['name'],
                              'log'   => ''
                          );
      // enregistre le battement de coeur en base de données dans la table heartbeat
      $add        = addData ('heartbeat', $field_data);

      // titre du mail à envoyer
      $mail_title = 'Pi TimeLapse - HeartBeat '.date("d.m.y H:i:s");

      // corps du mail à envoyer, contenant la date et la minature
      $mail_core  = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
                      <html>
                        <head>
                          <title>'.$conf['site_name'].'</title>
                          <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
                          <meta http-equiv="Content-Language" content="Fr" />
                          <META name="Author" lang="fr" content="MagdiWeb" />
                          <META name="Copyright" content="© MagdiWeb" />
                        </head>
                        <body>
                          '.$mail_title.'<br>
                          '.$field_data['log'].'<br>
                          <img src="http://pi_timelapse/'.$conf['upload_dir'].'/'.$_FILES['img']['name'].'">

                        </body>
                      </html>';

      // envoie le mail
      $mail       = mailIt ('mon_adresse_mail@mail.fr', $mail_title, $mail_core);
      logIt('access', $mail_title);
    }
    else {
      logIt('access', 'unable to mv uploaded file '.$_FILES['img']['name']);
    }
  }
  else{
    logIt('access', 'error during file upload ...');
  }

}
else{
  logIt('access', 'wrong heartbeat token ...');
}

// écrit l'ensemble des messages/logs dans un fichier
writeLog ();

?>

Voici une screenshot du mail que je reçois sur mon smartphone lors de la réception d’un battement de coeur de la part du Pi (sur la photo on voit un bout de mon bureau,… c’est pour les tests 😉 :

photo

Dashboard

J’ai également prévu une page type dashboard qui affiche toutes les miniatures reçues avec les dates. Pour le moment, je ne publie pas cette page, mais lorsque le chantier commencera, je la synchroniserai avec ce blog afin que vous puissiez suivre en directe l’évolution des travaux, et constater que le dispositif fonctionne bien 🙂

Toujours aussi minimaliste, le but est simplement d’afficher l’ensemble des miniatures sous forme d’une mosaïque d’images.

<?php

header('Content-type: text/html; charset=utf-8');

require_once('conf.php');
require_once('func.php');

$session_id = sessionStart();
$db_connect = dbConnect();
$_REQUEST   = clearRequest ($_REQUEST);

if(!empty($_REQUEST['token']) && $_REQUEST['token'] == $conf['token']['index']) {

$heartbeats = selectAll ('heartbeat');

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title><?php echo $conf['site_name']; ?></title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <meta http-equiv="Content-Language" content="Fr" />
    <META name="Author" lang="fr" content="MagdiWeb" />
    <META name="Copyright" content="© MagdiWeb" />  
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
    <?php
      $nb_heartbeat = sizeof($heartbeats);
      echo '('.$nb_heartbeat.' beats)';
    ?>
    <table>
    <?php
      $c = 0;
      foreach($heartbeats as $heartbeat) {
        if($c == 0){echo '<tr>';}
        echo '<td>'.humanDate ($heartbeat['date'], 'full').'<br><img src="'.$conf['upload_dir'].'/'.$heartbeat['img'].'"></td>';
        $c++;
        if($c == 4){$c=0; echo '</tr>';}
      }
    ?>
    </table>

  </body>
</html>

<?php

}else{
  logIt('access', 'wrong index token ...');
}

writeLog ();

?>

Voici une screenshot de ce que cela donne pour l’instant (toujours avec des photos de test 😉 :

Screenshot-1

5 – Schéma global et utilisation

Le dispositif au complet se compose de trois éléments :

  • Le système de capture d’image
  • Le circuit de temporisation de l’alimentation
  • Un serveur de monitoring

schéma global Pi TimeLapse

Le système de capture d’image

Composé du Pi, d’une webcam, d’un dongle 3G et d’une batterie 5V, ce système se contente de prendre une photo à chaque démarrage, puis s’éteint immédiatement. Une fois sur trois, il envoi une requête au serveur de monitoring pour signifier que tout va bien 🙂

Le circuit de temporisation de l’alimentation

Ce circuit alimenté par une batterie 12V, pilote un relais électrique permettant de commander l’alimentation du Pi pendant 2 minutes toutes les 10 minutes, de 8h00 à 18h00, du lundi au vendredi.

Un serveur de monitoring

Un script PHP publié par un serveur web Apache permet d’enregistrer les requêtes POST envoyée par le Pi toutes les 30 minutes. Il réceptionne une miniature d’une la dernière photo prise, et enregistre l’heure exacte à laquelle il l’a reçu dans une base de données MySQL. Si tout est ok, il envoi un mail avec la date et la photo miniature, ce qui me permettra d’être continuellement averti du bon fonctionnement du système de capture d’image.

En parallèle, ce serveur web publie une page web, qui liste l’ensemble des miniatures ainsi enregistrées, ce qui permet d’avoir une vue d’ensemble du bon déroulement des choses sur une semaine.

Scénario d’utilisation

  1. Le circuit de tempo alimente le Pi qui boot immédiatement
  2. Une fois démarré, le Pi prend une phot et lance un shutdown
  3. Une fois sur trois (soit toutes les 30 minutes) le Pi envoi une requête sur un serveur de monotoring distant pour dire qu’il est toujours en vie
  4. Le circuit de tempo coupe l’alimentation du Pi après 2 minutes