Système de vidéo-surveillance abordable avec des Raspberry Pi

IMG_6646

Aujourd’hui nous allons voir comment créer un système de télé-surveillance grâce à un Raspberry Pi et divers types de caméras.

Ce système a pour vocation d’être utilisé dans le cardre d’une télé-surveillance domestique. Il doit permettre de garder un oeil en temps réel sur sa maison, et sauvegarder un historique des images en cas de besoin.

La capture d’écran ci-dessous vous donne un aperçu du résultat final du système qui est actuellement installé chez moi. J’ai volontairement flouté les images pour conserver l’intimité de mon « chez moi ». Je dispose de quatre caméras (une webcam, une caméra IP et deux module Raspberry Pi Caméra dont un NoIR pour la vision nocturne) :

video_surveillance_monitorin_safe

Nous verrons comment utiliser trois différents types de caméras pour vous permettre de construire votre système avec le matériel dont vous disposez déjà :

Si vous souhaitez vous équiper, je vous conseille fortement d’opter pour le module Raspberry Pi Caméra, très petit, qui offre un rapport qualité/prix imbatable. En outre le modèle NoIR vous permettra de voir la nuit grâce un projecteur infra rouge :)

Note : Je ne reviens pas ici sur l’installation et l’utilisation de ces caméras. Il existe de nombreux tutos sur le net, que ce soit pour les webcam, les caméras IP ou le module Raspberry Pi Camera. Cet article se concentre sur la création du système de télé-surveillance.

Le principe global du système

Le système se compose d’un ou plusieurs Raspberry Pi équipés chacun d’une caméra (quelque soit son type) et d’un Raspberry Pi de « contrôle » qui centralise les images. Les Raspberry Pi se contentent de prendre une photo à intervalles réguliers et de les envoyer en WiFi ou Ethernet au Raspberry Pi de « contrôle ». Chaque image est taguée avec le nom de la caméra dont elle provient, et la date à laquelle elle a été prise afin de pouvoir la situer dans le temps.

Le Raspberry Pi de « contrôle » archive toutes les images qu’il recoit et peut effectuer des traitements dessus pour détecter des mouvements par exemple. Il est également équipé d’une interface Web permettant de consulter les images à distance depuis n’importe quel device ou navigateur web.

rasperry_pi_camera_surveillance_systeme

Photo ou vidéo ?

Quand on parle de « vidéo surveillance », on s’imagine un flux « vidéo ». Or, dans la pratique, ce n’est pas forcément le cas. D’une part parce que ce n’est pas forcément utile, et d’autre part parce que c’est problématique d’un point de vu « bande passante » pour un usage domestique.

Problème réseau

Le problème se pose si l’on souhaite regarder les images prises par une caméra à distance. Il faut faire transiter ces images entre la caméra, et le poste de visionnage. Or, un flux vidéo nécessite une bande passante conséquente pour afficher les images en continue et de manière fluide. Surtout lorsqu’on utilise des résolutions importantes de plusieurs méga-pixels.

Pour résoudre ce problème, on peut soit baisser la qualité de l’image, soit baisser le nombre d’images prises par seconde (rappelons qu’une vidéo n’est autre qu’un enchainement de photos).

Dans la pratique il faudra faire les deux, surtout si vous souhaitez pouvoir visonner les images en passant par un mobile en 3G.

L’utilité de la vidéo par rapport aux photos

Un système de vidéo surveillance, ou de télé-surveillance, domestique doit selon moi, permettre deux choses :

  • voir en directe ce qui se passe à la maison à distance (Est ce que tout se passe bien à la maison ? Ai-je oublié d’éteindre mes lumières ?). Une photo prise régulièrement suffit.
  • avoir une trace d’un évènement qui s’est déroulé (Avoir des preuves d’un cambriolage ou d’un incendie, et pouvoir les utiliser pour l’enquête). Cela nécessite de stocker les images pendant un certain temps.

L’important, c’est d’avoir les images en temps réel, de pouvoir les stocker et les visonner facilement, sur place ou a distance. Dans ces conditions, nous pouvons nous satisfaire d’une photo par seconde, voire moins :) C’est exactement le principe du MJPEG qui est largement utilisé dans de nombreuses caméras IP. Le célèbre logiciel de détection de mouvement Motion, fonctionne également sur ce principe :)

Le gros avantage de la photo par rapport à la vidéo pour la télésurveillance

Demander à une caméra de prendre une photo à intervalles réguliers plutôt qu’une vidéo a également de nombreux avantages et permet grande souplesse d’utilisation :

  • entre chaque photo, votre caméra ou votre Raspberry Pi est disponible pour faire autre chose
  • une photo peu être prise et stockée en haute résolution puis facilement réduite pour être affichée à distance. On peut ainsi garder un historique des photos ou évènements en haute définition 1080p, et consulter avec son mobile en 3G une miniature de ces photos.
  • une photo prise, peut être immédiatement envoyée sur un serveur distant pour y être sauvegardée et archivée. Un voleur pourra saboter votre caméra, mais toutes les photos prises auront déjà été sauvegardée :)
  • il est très facile de détecter un mouvement en comparant deux photos :)
  • il est très facile de créer une vidéo à partir d’images qui se suivent :)

Nous allons maintenant voir comment créer notre système de télé-surveillance en commençant par son noeud central, le Raspberry Pi de « Contrôle » :)

Le Contrôleur

Pour réaliser ce « contrôleur« , vous pouvez utiliser n’importe quel Raspberry Pi (ou n’importe quel ordinateur d’ailleurs ;) ) relié à votre réseau, en WiFi ou Ethernet. Vous choisirez une carte mémoire en fonction du nombre de caméras dont vous disposez, de la qualité des images, et du nombre d’images que vous souhaitez conserver.

La première étape consiste à installer et configurer un serveur web Apache et PHP5. Je vous propose de suivre la procédure décrite dans cette article : PiHomeDashScreen – Installation et configuration. Ce serveur web servira à récupérer les images envoyées en HTTP POST et à diffuser l’interface web de visionnage.

Script de réception des images

Le principe est simple, les images seront envoyées en HTTP POST par les Raspberry Pi équipé d’une caméra, il nous suffit donc de créer un petit script en PHP pour les réceptionner.

collect.php :

<?php

$token    = 'azerty'; // token qui sert de mot de passe
$dst_dir  = 'camera'; // nom du dossier dans lequel seront stockées les images

if(isset($_REQUEST['token']) && $_REQUEST['token'] == $token){

  if(isset($_REQUEST['camera_name'])){

    $camera_name = $_REQUEST['camera_name'];  // nom de la caméra envoyé en même temps que l'image
    $img_name    = 'cam_'.$camera_name.'_'.time().'.jpg';   // nom du fichier image à stocker : prefixe, nom de la camera et timestamp

    if(!is_dir($dst_dir)){mkdir($dst_dir, 0777, true);}  // créé le répertoire de stockage s'il n'existe pas
    if(!is_dir($dst_dir.'/'.$camera_name)){mkdir($dst_dir.'/'.$camera_name, 0777, true);}  // créé un sous répertoire pour chaque caméra s'il n'existe pas

    if (is_uploaded_file($_FILES["camera_image"]["tmp_name"])) {
      move_uploaded_file($_FILES["camera_image"]["tmp_name"], $dst_dir.'/'.$camera_name.'/'.$img_name); // enregistre l'image réceptionnée dans le bon répertoire
    }
  }
}

?>

Pour visionner les images nous allons créer une page index.php qui affiche la dernière image de chaque caméra. Une fonction JavaScript se charge de raffraichir les images à intervalles réguliers :)

<?php

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

  // nom du dossier dans lequel sont stockées les images
  $dst_dir  = 'camera';

  // liste des caméras à afficher
  $cameras = array('visioncam', 'egeon', 'carpo', 'triton');

  // taille d'affichage des images
  $width  = '640';
  $height = '480';

  // fonction qui renvoie la dernière image d'une caméra
  function showLastImage ($cam_name) {
    global $dst_dir;
    header('Content-type: image/jpeg');
    $dir  = $dst_dir."/".$cam_name."/cam_".$cam_name."_*";
    $imgs = glob($dir);
    echo new Imagick(end($imgs));
  }

  if(isset($_REQUEST['get_cam_img'])){
    echo showLastImage($_REQUEST['get_cam_img']);
  }
  else{

?>

  <!DOCTYPE html>
  <html>
    <head>
      <title>Cameras</title>
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
      <style>
        body { text-align : center; background-color : #000;}
        div.camera { display : inline-block; text-align : center; margin : 5px }
        img.camera { width : <?php echo $width; ?>px; height : <?php echo $height; ?>px; }
      </style>
    </head>
    <body>

      <?php foreach($cameras as $camera){ ?>
        <div id="<?php echo $camera; ?>">
          <img id="img_<?php echo $camera; ?>" src="">
        </div>
      <?php } ?>

      <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
      <script>
        var refresh = 3000;

        $( document ).ready(function() {
          setInterval(function() {
            var now = new Date().getTime();
            $("div.camera").each(function( index ) {
              var camera_name = $( this ).attr("id");
              console.log( "refresh "+camera_name+"..." );
              var url = 'index.php?get_cam_img='+camera_name;
              var img_tmp  = $("<img />").attr("src", url+"&"+now);
              $("#img_"+camera_name).attr("src", url+"&"+now);
            });
          }, refresh);
        });
      </script>

    </body>
  </html>

<?php } ?>

ATTENTION : De même que dans l’article « Contrôle de l’éclairage avec le module Z-Wave Razberry », le code source ci-dessus est créer dans le cadre d’un exemple simple, il peut et doit être optimisé et sécurisé :)

Si vous souhaitez avoir accès à cette application web depuis l’extérieur de votre réseau local, je vous conseille fortement de mettre en place un contrôle d’accès afin d’éviter que n’importe qui ne puisse visionner vos caméras et espionner votre maison :)

Dans un prochain article, je décortiquerai une installation complète et sécurisé à double authentification : certificat client et mot de passe.

En attendant, vous pouvez sécuriser l’accès à votre système en demandant un login/mot de passe grâce à un fichier .htacces comme expliqué dans ce tuto : http://www.commentcamarche.net/contents/7-apache-les-fichiers-htaccess

Voyons maintenant comment prendre des photos à intervalles réguliers et les envoyer au « contrôleur » :)

Prendre des photos et les envoyer au contrôleur

Sur chaque Raspberry Pi équipé d’une caméra, vous devrez exécuter le script camera_shot.sh suivant :

#!/bin/bash

camera_name="egeon"
dst_url="http://ip_controleur/collect.php"
refresh=5 # delais entre chaque photo

while true ; do
  img_tag=$camera_name" - "`date "+%Y-%m-%d %A %B %H:%M:%S"`
  img_name="cam_img.jpg"

  ##################################################################
  # POUR LES MODULES RASPBERRY PI CAMERA
  ##################################################################
  raspistill -t 1 -w 640 -h 480 -q 50 -o $img_name

  ##################################################################
  # POUR LES WEBCAMS USB
  ##################################################################
  streamer -c /dev/video0 -f jpeg -s 640x480 -j 50 -o $img_name".jpeg" && mv $img_name".jpeg" $img_name

  ##################################################################
  # POUR LES CAMERAS IP 
  # (le nom du script snapshot.cgi peut dependre du modele de camera)
  ##################################################################
  curl -o $img_name".jpeg" http://adresse_ip_camera/snapshot.cgi && mv $img_name".jpeg" $img_name

  ##################################################################

  if [ -f $img_name ] ; then
    convert -pointsize 15 -undercolor black -fill white -draw 'text 0,12 "'"$img_tag"'"' $img_name $img_name
    curl --form camera_image=@$img_name --form camera_name=$camera_name --form token=azerty $dst_url
    rm $img_name
  fi
  sleep $refresh
done

Vider l’historique des images sur le contrôleur

Si vous utilisez le système dans l’état les images vont s’entasser sur le contrôleur indéfiniment. A titre d’exemple, si vous prenez des photos en 640×480 px toutes les 5 secondes avec une moyenne de 30Ko par photo, cela représente environ 500Mo de données par jour et par caméra ! Avec mes quatre caméras, je génère donc près de 2Go de photo toutes les 24 heures :)

Il convient donc de supprimer les photos au bout d’un certain temps. Pour ma part je conserve un historique de 2 jours seulement.

Pour supprimer automatiquement les photos de plus de 2 jours, vous pouvez appeler ce script clean_cam.sh dans une CRON task :

#!/bin/bash

for i in `find /var/www/camera/* -type d` ; do
  find $i -type f -mtime +2 -exec rm -f {} \;
done

Vision de nuit

Si comme moi vous souhaitez profiter de la vision nocture que permet le module Raspberry Pi Camera NoIR, vous pouvez facilement construire un petit projecteur infrarouge grâce à quelques LED de ce type : LED IR 5mm 53Sf4Bt Kingbright

J’ai réalisé un petit montage qui se branche directement sur la broche 5V du GPIO du Pi :

IMG_6537Cela fonctionne bien mais sur une très courte distance (< 3 mètres). Il faudrait des LEDs beaucoup plus puissantes pour éclairer une grande pièce. Dans tous les cas, vous devrez choisir des LEDs infra rouge ayant une longueur d’onde autour des 880nm.

Pour les grandes pièces, ou la carrément éclairer votre jardin, vous pouvez utilisez un projecteur infra rouge spécialement prévu pour cet usage. J’ai pu en voir plusieur, et mon choix s’est arrêté sur celui ci :

IMG_6542Vous pourrez le trouvez ici : http://www.selectronic.fr/projecteur-infrarouge-50m.html

D’une grande qualité de fabrication, et équipé d’un détecteur de luminosité, ce projecteur étanche et alimenté en 12V éclairera sans problème votre jardin ou votre séjour :)

Avec le module Raspberry Pi Camera NoIR dans l’obscurité la plus totale, on y voit comme en plein jour :)

Très prochainement je publierai un article expliquant comment créer la caméra IP ultime à partir d’un Raspberry Pi. A suivre…

BerryIO, une interface web pour contrôler tous les ports et bus du Raspberry Pi

En surfant sur le blog de mon confrère framboise314 je suis tombé sur cet article très complet qui parle de l’ilmpressionnante interface web BerryIO : http://www.framboise314.fr/berryio-trop-beau-pour-etre-vrai/

berryioIl s’agit d’un logiciel installable sur votre Raspberry Pi et qui vous permettra de prendre le contrôle de tous les ports et bus du Pi et d’obtenir de nombreuses informations système.

Voici la liste des fonctionnalités de BerryIO qui fonctionne sur toutes les versions du Raspberry Pi :

  • Contrôle intégral du port GPIO
  • Contrôle du module caméra
  • Gestion du bus SPI DAC/ADC
  • Gestion des afficheurs LCD et VFD HDD44780 et KS0066U
  • Affichage de la fréquence et de la température du CPU
  • Affichage de l’utilisation de la RAM et des points de montage
  • Affichage de la bande passante réseau et du signal WiFi
  • Une interface en ligne de commande reprennant toutes les fonctionnalités de l’interface web
  • Notification par email
  • Système de mise à jour
  • Une API dédiée

Un énorme travail de qualité avec une roadmap bien chargée : http://frozenmist.co.uk/downloads/berryio/

Pour plus d’information, consultez la page github du projet : https://github.com/NeonHorizon/berryio

Contrôle de l’éclairage avec le module Z-Wave Razberry

IMG_6233

Dans mon précédent article « transformez votre Raspberry Pi en serveur domotique Z-Wave », je vous présentais le module Razberry de Z-Wave.me. Aujourd’hui, nous allons voir en détail comment utiliser cette carte d’extension pour contrôler l’allumage et l’extinction de lampes.

Module prise de courant On/Off : Everspring AN157-6

Parmi les nombreux modules Z-Wave existants, nous allons ici utiliser un module très basique qui se branche sur une prise de courant 220V standard. Doté d’une simple fonction On/Off, ce module Everspring AN157-6 est disponible à environ 38€ sur les sites spécialisés comme celui-ci : http://www.planete-domotique.com/prises/modules-prises/zwave/prise-on-off-z-wave-fr-everspring-an157-6.html

IMG_6235 IMG_6234

IMG_6241D’une excellente qualité de fabrication et capable de supporter jusqu’à 3500W sur 16A, vous pourrez utiliser ce module pour piloter tous les appareils (ou presque) de votre maison (lampe, petit électroménager, appareil multimédia,…). Sur la face avant, il y a un bouton qui sert d’interrupteur manuel doté d’un témoin lumineux rouge qui s’allume lorsque la prise est en position « On« .

Bien que le boitier semble volumineux, il reste relativement discret comme vous pouvez le constater sur les photos ci-contre et ci-dessous.

IMG_6242A l’heure où j’écris cet article, je dispose de cinq de ces modules : lampe de la cuisine, lampe du bureau, lampe du séjour, lampes autour de la télé, et un pour le sapin de Noël :)

Razberry et Z-Way

IMG_6239Revenons en au module Razberry. Une fois enfiché sur le port GPIO du Pi, il ne vous reste plus qu’à booter et installer Z-Way, le soft proposé par Z-Wave.me.

Note : Z-Way est encore en béta, son aspect n’est donc pas aussi travaillé que ce dont on a l’habitude de nos jours, et les fonctionnalités restent limitées. Toujours est-il que les manques fonctionnels actuels peuvent être contournés facilement grâce à une API JSON :)

L’installation de Z-Way sur Raspbian se fait très simplement grâce au script mis à disposition sur le site du fabricant :

wget -q -O - razberry.z-wave.me/install | sudo bash

A la fin de l’installation, il suffit de rebooter le Pi. L’interface web de Z-Way est alors disponible directement sur le port TCP/8083 :) En vous connectant avec votre navigateur web, vous aurez le choix entre quatre interfaces.

z-way_razberry_1Pour continuer, nous choisirons l’interface « Expert » qui est la plus complète (les autres interfaces étant plus des démonstrations, pour montrer le potentiel de Z-Way).

Association des modules

La première chose à faire, est d’associer (ou d’inclure pour coller ay langage Z-Wave ;) ) nos modules « prise de courant » à notre contrôleur Z-Wave Razberry afin de créer un réseau Z-Wave. Pour cela, il suffit de se rendre dans le menu « Network->Network management » et de cliquer sur le bouton « include device« .

z-way_razberry_2A ce moment là, Z-Way est à l’écoute d’un module désirant entrer dans le réseau. Sur les modules Everspring AN157-6, rien de bien compliqué, il suffit de maintenir le bouton appuyé quelques secondes jusqu’à ce que le témoin lumineux clignote (ce qui indique que le module est en mode « inclusion« ). Au besoin, voici le mode d’emploi du module : everspring_an157_doc.pdf

Note : Pour vous familiariser la technologie Z-Wave et son jargon, je vous propose de lire cet article http://domotique-info.fr/technologies-domotique/zwave/

Une fois les modules correctement ajoutés dans le réseau Z-Wave, on peut voir l’état de chacun d’eux, et les tester grâce aux boutons « On/Off » :) (notez bien les numéros ID des modules, nous en aurons besoin un peu plus tard)z-way_razberry_3Jour ! Nuit ! Jour ! Nuit ! Jour ! Nuit ! Je vous vois rigoler, mais je vous garantis que vous ferez la même chose ;)

Vous en conviendrez, cette interface web, bien que tout à fait fonctionnelle, n’est pas très sexy…

Nous allons maintenant créer notre propre interface web adaptée à un affichage sur smartphone :)

Prendre le contrôle grâce à l’API web de Z-Way

Je vous conseille de lire cette article très complet sur le sujet : http://www.openremote.org/display/docs/OpenRemote+2.0+How+To+-+Z-Wave+with+Razberry

Maintenant que vous savez tout à propos de cette fameuse API, nous allons créer une petite application web en HTML/PHP5/JavaScript.

Et voilà le résultat final sur mon smartphone :)

IMG_6243

Note : Vous pouvez construire cette l’application web, soit directement sur le Pi qui détient le module Razberry, soit sur n’importe quelle autre machine :) Pour ma part, l’application web est exécutée sur un serveur tier :)

La première étape consiste à installer et configurer un serveur web Apache et PHP5. Je vous propose de suivre la procédure décrite dans cette article : PiHomeDashScreen – Installation et configuration

Une fois votre serveur web opérationnel, vous pouvez créer un répertoire « z-way » dans le répertoire par défaut d’Apache « /var/www », et y placer les fichiers décrits ci-après. L’idée est simple, il s’agit d’une simple page web qui représente chaque module par une image en forme d’ampoule (allumée ou éteinte). Lorsqu’on clique sur une ampoule, on envoie une requête AJAX qui enverra à son tour la requête HTTP GET à l’API Z-Way pour répercuter l’ordre donné :)

index.php

<?php
  header('Content-type: text/html; charset=utf-8');
  require_once('conf.php');
?>

<!DOCTYPE html>
<html>
  <head>
    <title>Z-Way - BOAs</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <meta http-equiv="Content-Language" content="Fr">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" media="screen" href="style.css">
  </head>
  <body>

    <?php foreach ($devices as $device_name => $device_id) { ?>
      <div onClick="zWave_AN157_set('<?php echo $device_id; ?>');">
        <img id="light_<?php echo $device_id; ?>" src="light_off.png">
        <p><?php echo $device_name; ?></p>
        <input style="width : 50px;" type="hidden" value="" id="status_<?php echo $device_id; ?>">
      </div>
    <?php } ?>

    <div onClick="zWave_AN157_set_all('on');">
      <img id="light_all_on" src="light_on.png">
      <p>All ON</p>
    </div>

    <div onClick="zWave_AN157_set_all('off');">
      <img id="light_all_off" src="light_off.png">
      <p>All OFF</p>
    </div>

    <script type="text/javascript" src="jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <script>
      $( document ).ready(function() {
        console.log( "ready!" );
        updateStatus ();
      });
    </script>

  </body>
</html>

 conf.php

<?php

// nom des modules ainsi que leur ID que vous trouverez dans l'interface web z-way

$devices = array(
                      'Cuisine' => 3,
                      'Salon'   => 6,
                      'Télé'    => 5,
                      'Bureau'  => 2,
                      'Sapin'   => 4
                  );

// adresse IP du Pi sur lequel Z-Way est installé

$pi_zway = "1.2.3.4";

?>

ajax.php

<?php

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

  function httpGet ($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $return = curl_exec($curl);
    curl_close($curl);
    return $return;
  }

  $cmd        = $_REQUEST['cmd'];
  $val        = $_REQUEST['val'];
  $device_id  = $_REQUEST['device_id'];
  if($val == 'on'){$val = 255;}else {$val = 0;}

  // permet de changer l'état d'un module
  if($cmd == 'set'){
    $url = "http://".$pi_zway.":8083/ZWaveAPI/Run/devices[".$device_id."].instances[0].commandClasses[0x25].Set(".$val.")";
    echo httpGet ($url);
  }

  // permet de récupérer l'état d'un module
  else if($cmd == 'get'){
    $url = "http://".$pi_zway.":8083/ZWaveAPI/Run/devices[".$device_id."].instances[0].commandClasses[37].Get()";
    echo httpGet ($url);
  }

  // permet de modifier l'état de  tous les modules
  else if($cmd == 'set_all'){
    foreach($devices as $device_name => $device_id) {
      $url = "http://".$pi_zway.":8083/ZWaveAPI/Run/devices[".$device_id."].instances[0].commandClasses[0x25].Set(".$val.")";
      echo httpGet ($url);
    }
  }

  // recupère le dernier statut
  else if($cmd == 'status'){
    $url = "http://".$pi_zway.":8083/ZWaveAPI/Data/".time();
    echo httpGet ($url);
  }

  // default
  else{
    return "";
  }

?>

main.js

Note : N’oubliez pas de télécharger la dernière version de jQuery

var status_timeout;

/* Z-Way */

function zWave_AN157_set_all (val) {
  $.ajax({
    async : false,
    type: "POST",
    url: "ajax.php",
    data: "cmd=set_all&val="+val,
    success: function(html){
      zWay_status_all ();
    }
  });
}

function zWave_AN157_set (device_id) {
  var status = $("#status_"+device_id).val();
  if(status == '255'){
    var val = 'off';
  }
  else{
    var val = 'on';
  }
  $.ajax({
    async : false,
    type: "POST",
    url: "ajax.php",
    data: "cmd=set&device_id="+device_id+"&val="+val,
    success: function(html){
      zWave_AN157_get (device_id);
    }
  });
}

function zWave_AN157_get (device_id) {
  $.ajax({
    async : false,
    type: "POST",
    url: "ajax.php",
    data: "cmd=get&device_id="+device_id,
    success: function(html){
      zWay_status (device_id);
    }
  });
}

function zWay_status (device_id) {
  $.ajax({
    async : false,
    dataType: "json",
    type: "POST",
    url: "ajax.php",
    data: "cmd=status",
    success: function(html){
      var updatetime = html['updateTime'];

      if(typeof html['devices.'+device_id+'.instances.0.commandClasses.37.data.level'] != 'undefined'){
        var level      = html['devices.'+device_id+'.instances.0.commandClasses.37.data.level']['value'];
        if(level == '255'){
          $("#light_"+device_id).attr('src', 'light_on.png');
        }
        else{
          $("#light_"+device_id).attr('src', 'light_off.png');
        }
        $("#status_"+device_id).val(level);
      }

      $("#status").html(updatetime);
    }
  });
}

function zWay_status_all () {
  $(".device_status").each(function (index) {
    var ds_id = $(this).attr('id').split("_");
    var d_id  = ds_id[1];
    zWave_AN157_get (d_id);
  });
}

function updateStatus () {
  zWay_status_all ();
  status_timeout = setTimeout("updateStatus()", 10000);
}

style.css

body {
  padding : 20px 5px;
  font-family : Arial, Helvetica;
  font-size : 14px;
  text-align : center;
  background-color : #000;
  color : #EEE;
}

div.dev {
  border : solid 1px #000;
  display : inline-block;
  text-align : center;
  padding : 5px;
  margin : 5px;
}

div.dev:active {
  border : solid 1px rgba(255,255,255,0.3);
}

div.dev:hover {
  cursor : pointer;
}

img.light {
  width : 100px;
  height : 100px;
  border : 0;
}

p.device_name {
  font-weight : bold;
  text-align : center;
}

 Enfin, voici les deux images d’ampoules utilisées :

light_off light_on

Avertissement

Le code source ci-dessus est créer dans le cadre d’un exemple simple, il peut et doit être optimisé et sécurisé :)

Si vous souhaitez avoir accès à cette application web depuis l’extérieur de votre réseau local, je vous conseille fortement de mettre en place un contrôle d’accès afin d’éviter que n’importe qui ne prenne le contrôle de votre maison :)

Dans un prochain article, je décortiquerai une installation complète et sécurisé à double authentification : certificat client et mot de passe.

Programmer l’allumage et l’extinction des lumières à heure fixe

Il peut être intéressant de programmer l’allumage et l’extinction des lumières (ou tout autre appareil) à heure fixe. Pour cela, rien de plus simple, il suffit de lancer les requêtes HTTP GET à Z-Way en utilisant CRON :)

Voici ma crontab qui allume les lumières de mon séjour du lundi au vendredi de 7h à 8h, puis de 19h à 1h tous les jours de la semaine :)

# m h  dom mon dow   command

#########################
#  LIGHTS
#########################

 0  7 * * 1-5    /root/z-way_lights.sh on
 0  0 * * 1-5    /root/z-way_lights.sh off
 0 19 * * *      /root/z-way_lights.sh on
 0  1 * * *      /root/z-way_lights.sh off

Et voici le contenu du script /root/z-way_lights.sh :

#!/bin/bash

devices="2 3 5 6"

if [[ $# -eq 0 ]] ; then
  exit 1;
fi

if [ $1 == "off" ] ; then
  val=0
elif [ $1 == "on" ] ; then
  val=255
else
  exit 1;
fi

for n in $devices ; do
  wget -o ./z-way.api -O ./z-way.api http://127.0.0.1:8083/ZWaveAPI/Run/devices%5B$n%5D.instances%5B0%5D.commandClasses%5B0x25%5D.Set%28$val%29 
done

exit 0;

Tout cela fonctionne très bien depuis maintenant quelques semaines :) Il me tarde de faire l’acquisition d’autres modules Z-Wave :) Je pense notamment à des prises avec variateur telles que les Everspring AD142-6, pour allumer la lumière progressivement le matin dans la chambre lorsque le réveil sonne :D

Dans mon prochain article, je parlerai de vidéo surveillance :) A suivre…