Domotique à la maison
Objectif :
- Récupérer la température ambiante intérieure, extérieure, en sortie de chaudière, en entrée de chaudière.
- Contrôler la mise en marche de la chaudière
- Contrôler la mise en marche d'une lampe ( pour dissuasion de présence )
- Contrôler le reboot de ma freebox.
- Visualiser les températures sur une page web, lisible depuis mon téléphone portable.
- Afficher le niveau de la citerne de récupération d'eau de pluie, sur un afficheur LCD. Historisation des valeurs pour gestion.
- Gestion d'une mini centrale d'alarme (détection de mouvement).
-
Materiel :
- 1 micro PC Banana pi CPU
- 1 HDD 120Go minimum
- 4 Ports USB
- 1 Port Ethernet
- 2 Ports serie
-
- 1 Interface USB 1-Wire DS2490
- 1 Kit velleman 8 relais K8056
- 4 Capteurs de température
- 1 Contrôleur 1-wire
- 8 Interrupteurs 1-Wire
- 1 Détecteur PIR
- 1 Thermostat Aube TH140 (contrôlable à distance)
- 1 Afficheur LCD 4x20 avec chip HD44780
- 1 Module LCD2USB
- 1 Carte DVR (Chipset Techwell 6805)
- 1 sonde temperature 433 MHz Lacrosse
Logiciel :
Raspbian V3.1
Owfs pour la gestion du One-Wire
Apache / MySQL / PHP
K8056 pour linux, pour la gestion de la carte K8056
lcd4linux pour la gestion de l'afficheur LCD
Librairie Wiring bPi
Installation et configuration :
Raspian sur BananaPi:
Ce document n'a pas pour but de décrire l'installation d'un linux, la documentation Raspberry Pi étant très bien fournie, je vous laisse le soin de consulter les pages sur le site de votre distribution choisie.
Installation k8056 :
On récupère les sources et on compile :
k8056 est opérationnnel.
Voir article sur la version client/server, rubrique développement.
Gestion de l'affichage LCD :
Ayant des besoins particuliers, j'ai choisi d'installer la dernière version LCD4Linux 0.11.0-SVN-1129M
Cela permet éventuellement aux développeurs d'apporter des modifications.
Récupération des sources, compilation et installation
Afin de paramétrer l'afficheur, on alimentera le fichier /etc/lcd4linux.conf
voici mon script :
# Descripteur de l'interface Display LCD2USB { Driver 'LCD2USB' Size '20x4' # Bus 'lsusb | grep lcd2usb | cut -d " " -f2 | cut -b-3' # Device 'lsusb | grep lcd2usb | cut -d " " -f4 | cut -b-3' Bus '004' Device '003' Contrast 250 Brightness 50 Icons 7 # asc255bug 1 } # Variables Variables { sec 1000 dsec 500 disec 100 msg 'RAS' pipechar '|' dmin 30000 min 60000 T 500 # variable menu m 0 a 0 # item menu
MN 'Menu :' AQ 'Acquitez' ME 'Mise En' MH 'Mise Hors' # variable action C ' Confirmer' F ' Fait' } # WIDGET Widget pipe { class 'Text' expression pipechar width 1 align 'PC' } Widget NMenu { class 'Text' expression m = m == 4 ? 0 : m width 1 align 'L' update dsec } Widget Gmenu { class 'Text' expression I=m==0?(a=0;MN):I;I=m==1?(I=a==0?AQ:I;I=a==1?C:I;I=a==2?(exec('/home/al/aq.sh',T);m=0):I):I;I=m==2?(I=a==0?ME:I;I=a==1?C:I;I=a==2?(F;m=0):I):I;I=m==3?(I=a==0?MH:I;I=a==1?C:I;I=a==2?(exec('/home/al/al.sh',T);m=0):I):I width 13 align 'L' # update tock } Widget NAction { class 'Text' expression a = a == 3 ? 0 : a width 1 align 'L' update dsec } Widget GAlarme { class 'Text' expression exec('sh /home/script/RA.sh', dsec) width 15 align 'L' update dsec } Widget OW0Bar { class 'Bar' expression exec('sh /home/script/VAD.sh', min) length 10 max 100 min 0 direction 'E' update min } Widget OW0 { class 'Text' expression exec('sh /home/script/VAD.sh', min) width 3 align 'PC' update min } Widget Tciterne { class 'Text' expression file::readline('/home/script/tciterne', 1) width 4 align 'PC' update min } Widget OW1 { class 'Text' expression file::readline('/home/script/thermostat', 1) width 4 align 'PC' update min } Widget OW2 { class 'Text' expression file::readline('/home/script/etage', 1) width 4 align 'PC' update min } Widget OW3 { class 'Text' expression file::readline('/home/script/ext', 1) width 4 align 'PC' update min } Widget OW4 { class 'Text' expression file::readline('/home/script/cave', 1) width 4 align 'PC' update min } Widget iconealarm { class 'Icon' speed 800 Bitmap { Row1 '...*.' Row2 '....*' Row3 '..*.*' Row4 '*.*.*' Row5 '*.*.*' Row6 '..*.*' Row7 '....*' Row8 '...*.' } } Widget iconepluie { class 'Icon' speed 400 Bitmap { Row1 '*....|...*.|.*...|....*|..*..' Row2 '..*..|*....|...*.|.*...|....*' Row3 '....*|..*..|*....|...*.|.*...' Row4 '.*...|....*|..*..|*....|...*.' Row5 '...*.|.*...|....*|..*..|*....' Row6 '*...*|*...*|*...*|**..*|*****' Row7 '*...*|***.*|*****|*****|*****' Row8 '*****|*****|*****|*****|*****' } } Widget iconeselect { class 'Icon' speed 800 Bitmap { Row1 '.*...' Row2 '.**..' Row3 '.***.' Row4 '*****' Row5 '.***.' Row6 '.**..' Row7 '.*...' Row8 '.....' } } Widget iconetemp { class 'Icon' speed 800 Bitmap { Row1 '..*..' Row2 '..**.' Row3 '..*..' Row4 '..**.' Row5 '..*..' Row6 '.***.' Row7 '.***.' Row8 '.***.' } } Widget iconepourcent { class 'Icon' speed 800 Bitmap { Row1 '**..*' Row2 '**..*' Row3 '...*.' Row4 '..*..' Row5 '..*..' Row6 '.*...' Row7 '*..**' Row8 '*..**' } } Widget iconemenu { class 'Icon' speed 800 Bitmap { Row1 '.....' Row2 '*.***' Row3 '.....' Row4 '*.***' Row5 '.....' Row6 '*.***' Row7 '.....' Row8 '*.***' } } # Definition des touches Widget keyup { class 'Keypad' position 'up' state 'pressed' expression m = m + 1 ; a = 0 } Widget keydown { class 'Keypad' position 'down' state 'pressed' expression a = a + 1 } # Mise en forme sur l'afficheur Layout Default { Row1 { Col1 'iconetemp' Col2 'OW1' Col6 'pipe' Col7 'OW2' Col11 'pipe' Col12 'OW3' Col16 'pipe' Col17 'OW4' } Row2 { Col1 'iconepluie' Col2 'OW0' Col5 'iconepourcent' Col6 'iconetemp' Col7 'Tciterne' Col11 'OW0Bar' } Row3 { Col1 'iconealarm' Col2 'GAlarme' } Row4 { Col1 'iconemenu' Col2 'NMenu' Col3 'NAction' Col4 'GMenu' } Keypad1 'keydown' Keypad2 'keyup' } # FIN Display 'LCD2USB' Layout 'Default' |
Pour mes besoins, je dois Afficher 5 températures :
- Temp1 : Thermostat général
- Temp2 : Etage
- Temp3 : Extérieur
- Temp4 : Cave
- Temp5 : Citerne
Puis le niveau de ma citerne en % et sur un bargraph de 10 Caractère
Ensuite on affichera les alarmes détectées, avec les détecteurs concernés.
Puis le menu sur la dernière ligne :
J'ai défini mon afficheur comme ceci :
IconsT : Temp1 | Temp2 | Temp3 | Temp4
IconsP : NivNum % | IconsT : Temp6 | NivBar
IconsA : Message sur les Alertes
IconsM : Menu :
- Acquittement
- Mise en Fonction
- Mise Hors Fonction.
Le menu étant gérer par 2 boutons, le bouton du haut sert au défilement (Select), et le bouton du bas sert à l'entrée dans le sous menu et à la validation (Valid).
J'ai ajouté un décompteur invisible, qui permet de baisser le retro éclairage au bout de 10 secondes d'inactivité.
Si on appuie sur Select, le rétro éclairage se réactive pour 10 secondes.
Compilation de OWFS :
On récupère les sources et on compile :
Afin de démarrer owfs au lancement de la machine, j'ai crée ce script dans /etc/init.d
#!/bin/sh # description: Control OWFS as a Service prog=owfs prog_fs=owfs prog_serv=owserver prog_gest=owgest PATH=/opt/owfs/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin DAEMON_FS=/usr/local/bin/$prog_fs PIDFILE_FS=/var/run/$prog_fs.pid DAEMON_SERV=/usr/local/bin/$prog_serv PIDFILE_SERV=/var/run/$prog_serv.pid CONF=/etc/fuse.conf # Arguments to $prog_fs # ARG_SERV="-u --write -p 3001" # Arguments to $prog_fs # MOUNT_POINT="/mnt/1wire/" ARG_FS="-s 3001 --allow_other --write " test -x $DAEMON_FS || exit 0 case "$1" in start) echo -n "Initializing fuse ..." modprobe fuse echo "." wait 10 echo -n "Starting $prog_serv" start-stop-daemon --start --quiet --pidfile $PIDFILE_SERV --exec $DAEMON_SERV -- $ARG_SERV echo "." wait 10 echo -n "Starting $prog_fs" start-stop-daemon --start --quiet --pidfile $PIDFILE_FS --exec $DAEMON_FS -- $ARG_FS $MOUNT_POINT echo "." wait 10 ;; stop) echo -n "Stopping $prog_serv" killall $DAEMON_SERV echo "." wait 10 echo -n "Stopping $prog_fs" umount $MOUNT_POINT echo "." wait 10 ;; restart) sh $0 stop sh $0 start ;; *) echo "Usage: /etc/init.d/$prog {start|stop|restart}" exit 1 ;; esac exit 0 # end |
Puis dans /etc/init.d, faire update-rc owfs defaults
On vérifie le point de montage avec un ls /mnt/1wire
-----------------------------------------
Mes sondes de température étant connectées, et le capteur de niveau d'eau construit, on peut déjà afficher quelques informations :
Reste la phase de création des scripts de traitement, et les pages web pour les commandes et interprétations des informations.
On va créer un 'moteur' qui permet de traiter les éléments du bus One Wire, et d'alimenter les différents fichiers de données.
La gestion de l'alarme sera gérée directement par lcd4linux (Mise En, Mise Hors, Acquittement, Déclanchement)
La première question à se poser, combien de fois dans une heure nous devons rafraichir les données ?
Pour la sonde de niveau, 1 fois suffit largement.
Pour les températures, si on veut avoir des courbes précisent, toutes les minutes serai convenable.
Pour les détecteurs de présence, il faut être encore plus précis, toutes les secondes. Ces dernier étant géré directement par lcd4linux, nous n'intégrerons pas cette gestion dans notre 'moteur'.
Mais patience, je cherche.....
Liens :
http://www.thierry-jaouen.fr/dokuwiki/doku.php?id=brouillon_1-wire
http://vesta.homelinux.net/mediawiki/index.php/Bus_1-wire
http://vesta.homelinux.free.fr/site/wiki/the_k8056_interface_board_from_velleman_on_linux.html
http://www.digitemp.com/
http://rosset.org/linux/temperature/howto.html
http://www.owfs.org/
http://oww.sourceforge.net/index.html
http://www.hobby-boards.com
https://fedorahosted.org/digitemp/browser/Makefile
http://automation.binarysage.net/?p=1244
http://ssl.bulix.org/projects/lcd4linux/
http://www.harbaum.org/till/lcd2usb/index.shtml
http://www.lemaker.org/
http://www.bananapi.com/
http://raspbian-france.fr/