mardi 28 mai 2013

[RaspberryPI] Commander des prises de courant par radio fréquence via un émetteur 433Mhz

J'ai acheté un pack de prises télécommandées de ce style :

J'avais envie de les commander via une interface Web. Quoi de mieux qu'une RaspberryPI pour ca?
Pour cela j'avais besoin :
- une RaspberryPI
- Un pack de prises télécommandées (voir ci-dessus)
- Un émetteur/récepteur 433Mhz (http://www.evola.fr/product_info.php/kit-transmission-433mhz-compatible-arduino-p-162)

Note importante!

Ces prises que l'on trouve dans le commerce utilise la fréquence 433Mhz pour dialoguer. En fait elle ne dialogue pas vraiment.
La télécommande est codée via 5 interrupteurs que l'on place en position 0 ou 1.
La télécommande est généralement composée de 4 on/off permettant d'allumer ou d'éteindre chaque prise.
Chaque prise est composée de 2 séries d'interrupteurs, le premier correspond au code de la télécommande, et l'autre au numéro de la prise (généralement ce sont des lettres).
En gros lors de l'appui sur un bouton de la télécommande, elle émet un signal composé :
1) du numéro de télécommande
2) du numéro de prise
3) de l'état voulu de la prise

Le code envoyer par chaque bouton est toujours le même.

Pendant ce temps là, les prises écoutes et attendent leur code de déclenchement.

Il est donc très facile de sniffer le code et le renvoyer (Man in the middle) mais heureusement on ne sera pas obligé de sniffer le code puisque des gens ont déjà travaillé dessus.

Nous utiliserons la librairie rc-switch ré-écrite pour la RaspberryPI et qui permet d'émuler, via un émetteur RF 433Mhz, une télécommande. A noter que rc-switch utilise la librairie Wiringpi.
La librairie rc-switch est également disponible pour Arduino et permet d'utiliser le recepteur RF.

Passons à l'installation

A présent nous allons mettre en place notre application.

Paramétrage des prises

1) Dans ce tutoriel, nous allons positionner les interrupteurs de chaque prises sur ON ou 1 (11111). Attention on va faire ca uniquement sur le code correspondant à la télécommande (celui avec 5 interrupteurs).
2) Ensuite on va attribuer une lettre différente pour chaque prise (de A à D)
3) Pour être sûr que cela fonctionne régler la télécommande avec le même code (11111) et brancher chacune des prises. Tester ensuite à l'aide de la télécommande pour voir si chaque prise s'allume et s'éteint.

Branchement du module RF 433Mhz sur la RaspberryPI


1) Relier Vcc > PIN 2 (5V)
2) Relier GND > PIN 6 (GND)
3) Relier output > PIN 11 (GPIO17)

Installer et configurer WiringPI

Installer RC-switch-pi

Tester les interrupteurs

Maintenant que tout est opérationnel, on va allumer une de nos prises.
Pour cela, on va utiliser le fichier send du dossier rc-switch et on va lui passer en paramètres :
1 : le code de la télécommande
2 : le numéro de la prise (1=A ; 2=B ; 3=C ; 4=D)
3 : l'état dans lequel on veut voir la prise (1=allumée ; 0=éteinte)
Exécuter donc la commande suivante (si vous êtes dans le dossier rc-switch) qui va allumer la première prise :
sudo ./send 11111 1 1 
Pour l'éteindre :
sudo ./send 11111 1 0 

Si ca ne fonctionne pas :
1) vérifier que la prise n'est pas à une distance trop éloigner de l'émetteur
2) vérifier les branchements de l'émetteur sur la RaspberryPI
3) reprendre le tuto...

Mettre en place l'interface

Installation du serveur lighttpd

Une fois que ca fonctionne on va pouvoir rendre accessible cette fonctionnalité via une interface Web.
Pour cela on va installer lighttpd qui suffira pour ce dont on a besoin de faire :
sudo apt-get install lighttpd

Création de l'interface

On va utiliser la librairie ainsi qu'un thème JQuery, pour cela configurer et télécharger un thème en suivant ce lien.
Dézipper ce dossier.
Créer un fichier index.php à la racine et y coller le code ci-dessous. Cette page va afficher 4 radio-boutons qui vont permettre d'allumer ou d'éteindre nos 4 interrupteurs.
<!doctype html>
<html lang="us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0">
<title>Domo</title>
<link href="css/ui-darkness/jquery-ui-1.10.3.custom.css" rel="stylesheet">
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery-ui-1.10.3.custom.js"></script>
<script>
$(function() {
$( "#radioset1" ).buttonset();
$( "#radioset2" ).buttonset();
$( "#radioset3" ).buttonset();
$( "#radioset4" ).buttonset();

$( ".ui-buttonset" ).change(function(){
var housecode=$(this).children("input[name='housecode']").val();
var numcode = $(this).children("input[name='num']").val();
var state = $(this).children(":checked").val();
console.log(housecode+"  : "+numcode+" : "+state);
$.post("sendVal.php", {housecode:housecode, numcode:numcode, state:state}, function(data){
console.log(data);
});
});
});
</script>
<style>
body{
font: 62.5% "Trebuchet MS", sans-serif;
}
.demoHeaders {
margin-top: 2em;
}
#dialog-link {
padding: .4em 1em .4em 20px;
text-decoration: none;
position: relative;
}
#dialog-link span.ui-icon {
margin: 0 5px 0 0;
position: absolute;
left: .2em;
top: 50%;
margin-top: -8px;
}
#icons {
margin: 0;
padding: 0;
}
#icons li {
margin: 2px;
position: relative;
padding: 4px 0;
cursor: pointer;
float: left;
list-style: none;
}
#icons span.ui-icon {
float: left;
margin: 0 4px;
}
.fakewindowcontain .ui-widget-overlay {
position: absolute;
}
</style>
</head>
<body>
<div id="radioset1" class="ui-buttonset">
Lumière 1 :
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="1"/>
<input type="radio" id="radio1" name="radio1" class="ui-helper-hidden-accessible" value="1"><label for="radio1" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio2" name="radio1" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio2" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset2" class="ui-buttonset">
Lumière 2 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="2"/>
<input type="radio" id="radio3" name="radio2" class="ui-helper-hidden-accessible" value="1"><label for="radio3" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio4" name="radio2" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio4" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset3" class="ui-buttonset">
Lumière 3 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="3"/>
<input type="radio" id="radio5" name="radio3" class="ui-helper-hidden-accessible" value="1"><label for="radio5" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio6" name="radio3" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio6" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset4" class="ui-buttonset">
Lumière 4 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="4"/>
<input type="radio" id="radio7" name="radio4" class="ui-helper-hidden-accessible" value="1"><label for="radio7" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio8" name="radio4" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio8" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
</body>
</html>

On va ensuite créer un fichier sendVal.php qui va recevoir les instructions des radio-boutons à envoyer via l'émetteur RF.
<?php
if(isset($_POST)){
if(isset($_POST['housecode']) &&
isset($_POST['numcode']) &&
isset($_POST['state'])){
$housecode = $_POST['housecode'];
$numcode = $_POST['numcode'];
$state = $_POST['state'];
$command = "sudo ./home/pi/rcswitch-pi/send ".$housecode." ".$numcode." ".$state;
system(escapeshellcmd($command));
echo 'ok';
}
}

?>

Envoyer le contenu du dossier dans le dossier /var/www de la RaspberryPI.
Saisir ensuite l'IP de la RaspberryPI dans un navigateur. La page avec les 4 radio-boutons devrait s'afficher.

Tester l'un des radio-boutons. Si cela fonctionne tant mieux! Sinon il faut aller jeter un œil dans les logs.
Personnellement j'avais une erreur d'authentification de l'utilisateur www-data (utilisateur de lighttpd). J'ai réglé cela en ajoutant dans le fichier /etc/sudoers :
www-data ALL=NOPASSWD: ALL

Re-tester, ca devrait fonctionner.

4 commentaires:

  1. très intéressant, je souhaiterais utiliser la librairie rc-switch pour communiquer ma Raspberry via ma carte Arduino ( déjà réussi à faire communiquer deux Arduino avec le 433mhz) . Je souhaiterais simplement envoyé des signaux avec des entiers, sans état On ou Off , est-ce possible ?

    RépondreSupprimer
    Réponses
    1. Merci!
      Bien sur que c'est possible, j'ai déjà testé la communication entre RPI et Arduino ca fonctionne bien. Ca fait un petit moment mais un petit coup de Google et http://www.homautomation.org/2014/03/02/433mhtz-rf-communication-between-arduino-and-raspberry-pi-arduino-as-receiver/

      Supprimer
  2. Il y a une erreur dans ton tuto, (1 = allumé, 2 = éteint) c'est (1 = allumé, 0 = éteint)

    Sinon il a l'air top ce tuto, je vais l'essayer prochainement avec mes prises!

    RépondreSupprimer