Jan 16

Injection de données en temps réel sur un client web

Tout d’abord, comme il se doit, je vous souhaite à tous une excellente année 2011 !!!

Qu’elle vous apporte bonheur, santé, argent (accessoirement des filles nues déchainées dans votre lit le soir, une bande passante a 1Gbps, des groupies hurlant votre prénom a la sortie du travail et le retour de Karen Cheryl sur M6 Music (nan j’déconne Fred :p) ).

Plus sérieusement, tout le meilleur pour vous pour cette nouvelle année 🙂 et pour moi, de continuer a faire connaissance avec des bloggeurs/acteurs du net/forumeurs/ircéen de talent. Je ne peux vous citer tous de peur d’en oublier mais vous vous reconnaîtrez sûrement puisque, forcément, on a discuter ensemble ou par mail , ou sur IRC (pour ceux qui me cherche je suis sur les réseaux Europnet (pincipalement) et Freenode), ou sur les forums, ou par commentaires interposés. Merci à vous pour ses rencontres.

Alors nouveau billet pour cette année 2011. Alors oui, encore un peu lié à la domotique (quoi que…) (que voulez vous ça m’éclate en ce moment) mais je préfère rassurer mes lecteurs geeks intransigeants, on changera de sujet la prochaine fois 😉

Ce billet donc pour vous faire partager ce que j’ai mis en place à mon domicile.

Alors que je déploie petit à petit mon installation domotique, un des éléments essentiels de la maison reste l’interface reprenant tout les « services » disponibles.

Car au bout d’un moment, je me suis vite rendu compte qu’il y en avait partout 😀

Entre l’interface ZoneMinder pour les caméras, le Domus.link pour les interfaces X10, les diverses pages variées de mon cru remontant les appels téléphoniques entrant, les mails, la météo, les températures des pièces, Nagios, Cacti et j’en passe et des meilleurs… J’ai donc commencer l’année par créer un joli portail pour regrouper tout cela. (OMG, 2011 et je me mets à faire du dev… l’année commence mal 😉 ).

Je tiens a remercier d’ailleurs au passage Clément Storck (du blog du même nom :-p) pour son aide non négligeable au choix de la partie graphique de mon portail.

Et outre la centralisation de tout cela dans mon portail, une des fonctions que je souhaitais mettre en oeuvre, c’était l’injection dans la page web de messages provenant du serveur Domotique ou d’une autre source (Nagios par exemple) en temps réel.

Car je voulais éviter au possible les « refresh » de la page web toutes les X secondes et surtout, c’était bien le serveur qui devait envoyer les messages au client et non les clients qui se devait de « poller »/ »rafraichir » pour mettre a jour les informations.

J’ai donc fouiller un peu le Nain Ternet pour trouver une technique sympa pour faire cela et j’ai trouvé mon bonheur grâce à un projet OpenSource : AJAX PUSH ENGINE.

Pour les habitués de ses technos, il s’agit d’un serveur Comet, c’est à dire un serveur web qui push l’info aux navigateurx clients.

Vous trouverez plus d’infos sur le fonctionnement d’APE ici :

http://www.ape-project.org/ajax-push.html

NB: j’ai pris un peu de temps a fouiller le nain ternet et à récuperer des infos à droite à gauche et j’ai peut-être oublié de mentionner votre article correspondant, dans ce cas, n’hésitez pas à me conspuer que je vous cite (avec toutes mes excuses d’avance si je vous ai oublié).

Car oui, j’ai le respect de mes sources, et donc j’en profite pour faire un clin d’oeil a tout ceux qui pique sans vergogne mes billets sans me prévenir et surtout sans me citer, c’est toujours très sympa de lire ses propres lignes dans les billets/thèses/articles des autres sans se voir citer, a bon entendeur… (c’est d’ailleurs une des principales causes de ralentissement de publication de ce blog, le dégout de se voir copier parfois mot pour mot et qu’en plus on t’envoie ch… quand tu demandes juste un « merci de citer vos sources »…)

Heureusement pour moi, la documentation est abondante et assez compréhensible pour qu’un newbie comme moi en programmation y arrive 😀

Je vous invite donc à lire ses tutoriaux :

http://www.ape-project.org/wiki/index.php/Main/fr

http://www.lafermeduweb.net/tutorial/ape-ajax-push-engine-installation-configuration-et-developpement-d-une-application-basique-22.html

http://wiki.strycore.com/index.php/Ajax_Push_Engine

et surtout l’excellent blog de Paul, ifc0nfig.com, qui regorge de démos et code source :

http://www.ifc0nfig.com/using-jquery-with-ape-change-the-background-color-with-php/

http://www.ifc0nfig.com/diving-into-ape-modules-and-the-jsf-creating-topics-for-channels/

Allez, suffit pour les liens, passons à la mise en oeuvre :

  • Installation du serveur APE

La c’est super dur 😉

Rendez vous sur http://www.ape-project.org/download/APE_Server.html

J’ai télécharger le package Debian et un petit dpkg -i , c’est fini.

On configure le fichier /etc/ape/ape.conf

uid {
user = www-data
group = www-data
}
 
Server {
port = 6969
daemon = yes
ip_listen = 0.0.0.0
domain = guiguiabloc.fr

On le démarre : /etc/init.d/ape-server start

  • Modification du DNS local

NB: Il existe une méthode par VHOST Apache que je n’utilise pas, je vous laisser consulter la doc.

Petite bidouille a mettre en place sur votre serveur DNS local, il faut résoudre *.votreserveur.votredomaine.

En effet, vous devez créer un sous-domaine dédié au serveur APE capable de résoudre tout les alias (un catch-all CNAME) si vous préférez.

Dans Bind c’est très simple :

srv-domotique IN A 192.168.0.1
*.srv-domotique IN CNAME srv-domotique
  • Installation du Framework Javascript

Téléchargez le framework APE ici :

http://www.ape-project.org/download/APE_JavaScript_Framework.html

Par simplicité pour les tests, je l’ai décompressé a la racine de mon serveur Web (dans /var/www/)

Commencez par configurer le config.js dans /var/www/ape-jsf/Demos :

APE.Config.baseUrl = 'http://srv-domotique.guiguiabloc.frt/ape-jsf'; //APE JSF
APE.Config.domain = 'guiguiabloc.fr';
APE.Config.server = 'srv-domotique.guiguiabloc.fr:6969'; //APE server URL

Vous n’avez plus qu’a vérifier que tout fonctionne correctement avec l’outil disponible :

http://srv-domotique.guiguiabloc.fr/ape-jsf/Tools/Check/

Si tout se passe bien vous devriez avoir une confirmation du bon fonctionnement de votre serveur APE :

Running test : Setting document.domain
Running test : Checking APE.Config.baseUrl
APE JSF Version 1.0
Running test : Contacting APE Server
domain = guiguiabloc.fr
Running test : Contacting APE Server (adding frequency)
Running test : Initializing APE Client
Running test : Connecting to APE Server
All test done. Now you can play with your APE \o/
  • Mise en place du système de message temps réel

Je me suis basé sur la démo « APEController » fournie dans le framework.

Côté serveur web :

le config.js est le même que décrit plus haut.

le guigui.js :

APE.Controller = new Class({
Extends: APE.Client,
Implements: Options,
options: {
container: null
},
initialize: function(options){
this.setOptions(options);
this.container = $(this.options.container) || document.body;
this.onRaw('postmsg', this.onMsg);
this.addEvent('load',this.start);
},
start: function(core){
this.core.start({'name': $time().toString()});
},
onMsg: function(raw){
$('apeSendMsg').empty();
new Element('div', {
'class': 'message',
html: decodeURIComponent(raw.data.message)
}).inject(this.container);
},
});

Le fichier index.html :

...
</style>
 
        <script type="text/javaScript" src="../Clients/mootools-core.js"></script>
        <script type="text/javaScript" src="../Clients/MooTools.js"></script>
        <script type="text/javaScript" src="config.js"></script>
        <script type="text/javaScript" src="guigui.js"></script>
        <script type="text/javaScript">
                window.addEvent('domready', function(){
                        var client = new APE.Controller({
                                container: $('apeSendMsg')
                        });
                        client.load({
                                identifier: 'action',
                                channel: 'testchannel'
                        });
                });
        </script>
</head>
<body>
                <div id="apeSendMsg"></div>
</body>

Et voila, reste à ecrire un petit code en php pour injecter les messages :

<?php
$APEserver = 'http://srv-domotique.guiguiabloc.fr:6969/?';
$APEPassword = 'testpasswd';
$messages = array(
        $argv[1],
);
 
$cmd = array(array(
  'cmd' => 'inlinepush',
  'params' =>  array(
          'password'  => $APEPassword,
          'raw'       => 'postmsg',
          'channel'   => 'testchannel',
          'data'      => array(
              'message' => '<b>'.$messages[array_rand($messages)].'</b>'
          )
   )
));
 
var_dump($APEserver.rawurlencode(json_encode($cmd)));
$data = file_get_contents($APEserver.rawurlencode(json_encode($cmd)));

Ne reste qu’à tester 🙂

~/scripts$ php send_message.php "Yo Guigui, bien ou bien ?"
string(292) "http://srv-domotique.guiguiabloc.fr:6969/?%5B%7B%22cmd%22%3A%22inlinepush%22%2C%22params%22%3A%7B%22password%22%3A%22testpasswd%22%2C%22raw%22%3A%22postmsg%22%2C%22channel%22%3A%22testchannel%22%2C%22data%22%3A%7B%22message%22%3A%22%3Cb%3EYo%20Guigui%2C%20bien%20ou%20bien%20%3F%3C%5C%2Fb%3E%22%7D%7D%7D%5D"

Et sur le client Web, vous avez le message qui s’affiche :

Magique 😀

Maintenant il suffit de rajouter l’appel au script php dans votre x10.conf ou dans vos scripts Nagios pour que les messages soient poussés en temps réel dans votre page Web, sympa non ? 😉

On peut bien évidemment pousser plus loin le concept et par cette technique, changer à la volée les images sur le navigateur du client. Bien pratique pour ajouter un calque « rouge » sur l’image de la maison quand l’alarme est enclenchée par exemple 😉

Amusez-vous bien 😀

Classé dans architecture, geekerie | Taggé , , | 12 Commentaires
Déc 12

Travaux de geek

Ah la la, le temps passe et forcément, je délaisse un peu le blog….

En fait pas vraiment, je continue a répondre aux diverses questions et variées qui m’arrivent dans ma boite mail mais surtout, je continue a tester des nouveaux trucs et plus précisément, j’ai mis en place ma deuxième salle machine (aussi appeler « Datacenter salle E » par mon entourage ou projet Level 0 pour moi :-p )

Comme j’en suis pas peu fier, autant que je vous en fasse profiter (même si vous vous en foutez royalement 😀 )

La baie principal du bureau (Level 1 désormais) a un peu changé :

Baie Level 1

J’avais auparavant un routeur 2611XM et un Catalyst 2924 en « Coeur de Réseau », remplacé depuis par un Cisco 3550-48.

Dans la suite, de haut en bas, on trouve,  le Catalyst 2924 en spare,  le Soekris sous OpenBSD ,  le Cisco 2611XM qui devient firewal stateless, le Cisco PIX (firewall Statefull), un cisco 2620 (en maquette), un Cisco 3620 qui devient routeur de backbone entre le level 1 et le level 0.

L’interconnexion entre le bureau et le sous-sol se fait par une fibre optique Multimode.

Passage Fibre

Pour passer la fibre entre mon bureau et le sous-sol, j’ai condamné l’ancienne évacuation d’eau du bureau (auparavant un coin cuisine http://blog.guiguiabloc.fr/index.php/2008/01/30/montage-de-la-baie/ ). Les deux cables noirs en plus sont les coax des caméras filaires du sous-sol et de l’entrée du garage.

Enfin, la baie du sous-sol (Level 0 )

Baie Level 0

Sympa hein 🙂

L’électricité au sous-sol de ce côté etait déplorable, j’ai refait tout cela au propre :

Un petit tableau avec un disjoncteur de 16A et un différentiel 30mA (récup). Pour l’alimentation générale de la Baie, j’ai greffé un module AW12 en X10 dans une boite de dérivation qui me permet d’allumer/éteindre la baie par télécommande ou ordre X10 sur mon serveur Domotique.

La baie équipée (que de la récup’ 😉 ) :

Baie Level 0

De haut en bas :

– Serveur Dell 750 en attente

– Dell 750, Firewall Checkpoint SecurePlaform  FW-1 (Firewall  et Routeur de la zone level 0)

– HP Procurve 4000M : Switch Niveau 2 (extension du Level 1) avec son interco Fibre SX avec l’étage

– Cisco 2950, Switch Niveau 2 du Level 0

– Cisco 3620 , routeur du backbone Level0-Level1

– des Switchs SAN Brocade en attente de maquette

Classe non ? 😀

En attente, le cablage cuivre point a point entre le routeur de backbone level 0 et le routeur de backbone level 1.

Le routage est donc déporté sur ses deux routeurs interconnectés entre le Level 0 et le level 1.

Je vous reparlerais plus tard de la partie réseau de cette nouvelle installation (en OSPF bien sûr) et de la mise en oeuvre du Firewall Checkpoint FW-1 dans l’infra maison 🙂

Bref, de grands moments de plaisir (et de galère) a mettre tout cela en place 😉

A bientôt

Classé dans architecture, cisco, geekerie, matériel, réseau | 16 Commentaires
Sep 01

Qui c’est qu’a la plus grosse ?…

Ah ah ah, ce titre racoleur 😀

Non, rassurez-vous, dans ce billet je vous parlerai plutôt d’optimisation de site Web et non de ce à quoi vous pensez petit canaillou.

Récemment, je suis tombé sur un outil online permettant de réaliser un benchmark de votre site web.

Le site http://gtmetrix.com/ vous propose donc d’évaluer votre site grâce à des outils bien connus des développeurs : Yslow et PageSpeed.

Je n’ai jamais fait très attention au code de mon blog (bah oui, je ne suis pas du tout développeur 🙂 ), mais cet outil proposé par Gossamer (rien a voir avec les préservatifs hein… (ok, elle est très capilotractée cette blague :-p ) ) est assez intéressant pour plusieurs choses.
Tout d’abord connaître les « faiblesses » de votre site web, en apprendre un peu plus sur les choses à optimiser pour qu’il soit un tantinet plus rapide (surtout à forte charge) et bien sûr, améliorer son référencement. Car Google référencera plus facilement et devant les autres un site web dont le « Page Speed » est important.

Il y a plusieurs mois, je vous avez déjà parler de l’optmisation de mon blog via eAccelerator et Memcached dont les résultats comblaient toutes mes attentes.
Serein, je me suis donc empressé de « benchmarker » mon blog et oh surprise, c’était plutôt pas terrible du tout (yslow C et Page speed D).

En fait, a y regarder de plus près, et en passant d’autres blogs/sites à la moulinette, c’est un peu un cas général…

Ni une, ni deux, me sentant grandement motivé par ce challenge (oui gros challenge pour moi quand il s’agit de plonger dans du code php 🙂 ) je me suis attelé à suivre les conseils de Gtmetrix (via les liens Yahoo et Google).

Rien de bien difficile, et les résultats après quelques heures de travail sont surprenant.

D’ailleurs on se rend compte de pas mal d’erreur de conception dans WordPress et l’une des difficultés rencontrée était de positionner les codes javascript en pied de page.

Heureusement, Lyza Gardner nous a écrit un excellent tuto pour résoudre ce problème :

http://www.cloudfour.com/getting-all-javascript-into-the-footer-in-wordpress-not-so-fast-buster/

Tout cela c’est super, bien sympa, et puis on se dit, pourquoi pas plus ?…

Professionnellement, nous utilisons des CDN, des Content Delivery Network, dont le leader est Akamaï.

Il y a bien sur Amazon ou d’autres qui proposent ce genre de service, mais j’ai un gros faible pour Akamaï pour plusieurs raisons personnelles.

D’abord j’ai travaillé avec Akamaï lors de leur arrivée sur le marché français à la fin des années 90 (oui oui, j’ai eu une formation d’ intégrateur Akamaï :-p) et j’y ai cotoyé des gens formidables et très enrichissants professionnellement, qui plus est avec une techno révolutionnaire a cette époque (les membres de l’équipe de cette époque se rappeleront sans doute avec nostalgie le fameux coup de génie M6 Loft Story 😉 )

J’y ai perdu également une personne que j’aimais beaucoup, Daniel Lewin, un homme extrémement enrichissant que j’appréciais énormément et qui a eu le malheur de se trouver au mauvais endroit le 11 septembre 2001.

Bref, j’ai toujours était très attaché a cette entreprise (d’ailleurs mon premier site Web était gracieusement « akamaïsé » 😀 ), mais cela reste une offre professionnelle et pour un particulier disposant d’un simple blog, c’est un peu « too much » (et « too expensive » surtout..)

J’ai regardé du côté des CDN « gratuit » du genre CoralCDN dont le but est clairement intéressant mais ne semble plus suivi. Pourtant cela marche toujours et vous pouvez vous essayer à votre premier « CDN » avec eux.

Le CDN par soi-même, simple a mettre en oeuvre, il demande toutefois que vous disposiez de serveurs géographiquement distants et comble de la perfection, attachés a des points de peering intéressants.

Bref, j’avais un peu laisser tomber tout cela jusqu’a ce que je tombe la dessus :

http://code.google.com/p/cirruxcache/

« CirruxCache provides a software solution to dynamically cache HTTP objects on Google Appengine (using the Datastore and the Memcache services). »

En traduction demi-molle « CirruxCache vous permet de faire du cache HTTP via l’infrastructure Google Appengine ».

WTF ??? Alors ça, ca me semblait bien fun 😀

Je fouille un peu le site et oh surprise, Antoine Libert, sur son blog, nous offre un excellent tuto pour sa mise en oeuvre !!!

Tout d’abord, merci Antoine pour cet excellent article et le lien qu’il vous faut absolument lire :

http://a-l.fr/blog/2009/11/28/how-to-use-cirruxcache-and-google-app-engine-to-cache-static-content-of-your-wp-blog/

Rajoutez a cela, un superbe plugin WordPress pour les CDN :

http://mark.ossdl.de/2009/08/rewriting-urls-for-wordpress-and-cdn/

Le résultat est flagrant :

PageSpeed avec un score de 98….

Reste la comparaison avec d’autres sites pris au hasard 😉  :

Ok, on écrase google.com, free.fr ou ovh.fr (même si google se charge plus vite, forcément 🙂 )

On peut se la péter grave en société avec ça :mrgreen:

Donc tout cela pour vous dire que cette phase de travail a été enrichissante pour moi, que bien sûr il reste du boulot pour monter encore un c’hti peu (pas PageSpeed  hein, je crois qu’on ne peut pas monter plus haut, du moins, je n’ai trouver aucun site Web avec un tel niveau ou supérieur), mais comprendre un peu mieux une partie que je déteste d’habitude, le code 🙁 .

Bilan surtout sur CirruxCache et Google Appengine qui me parait une excellente solution de CDN dans des infras HA, permettant de soulager un peu vos serveurs, dans la limite, du moins, de ce que Google vous offre gratuitement comme ressource (après c’est payant bien sûr, faut pas déconner non plus…)

Amusez-vous bien 😀

Classé dans architecture, linux | Taggé , , , , | 9 Commentaires
Août 24

Domotique : synthèse vocale, Pulseaudio en unicast, Zoneminder et xAP, avec un soupçon de Sec…

En voila du titre bien décousu 🙂

En fait, j’ai passer quelques semaines a mettre en place différentes solutions dans mon environnement domotique et plutôt que d’en faire plein de petits billets, j’ai décidé de tout regrouper en un, à vous de piocher dedans 😀

Pour résumer la situation, je voulais d’abord que mon serveur Domotique « parle » (ça c’est plutôt simple), que lorsque j’allume mon portable au sous-sol, j’entende les messages audio du serveur (la ça se complique, si comme moi, vous ne souhaitez pas faire du multicast dans votre LAN), et enfin, comble du geekissime domotique, je voulais récupérer en temps réel les alarmes Zoneminder dès la détection d’un mouvement dans le champ de la caméra et que mon serveur Domotique me l’annonce de sa douce voix (la, ça se complique beaucoup, vous verrez…)

Bref, après plusieurs semaines, tout cela fonctionne, voyons comment.

  • SYNTHESE VOCALE ou comment faire parler une machine

Pour l’installation d’un synthèse vocale sur un serveur Linux, rien de plus simple.

Plutôt que de refaire un énième billet a ce sujet, je vous renvoie vers le blog de Christophe Nowicki dont je vous avez déjà parler, qui explique très bien la façon de le faire :

http://www.csquad.org/2009/08/27/text-to-speech-avec-espeak-mbrola-et-speech-dispatcher/

Il existe bien sûr d’autre tutos, mais Christophe a beaucoup travailler sur le « son » en Domotique et son blog regorge d’infos intéressantes.

Bilan après installation, un système de synthèse vocale installé sous /opt/mbrola

et bien sûr, les commandes essentielles à la création et gestion des « voix » :

(ps : fr4 est une voix française féminine, bizarrement je préfère :-p )

(NB: a l’attention de Fred, je n’arrive pas a reproduire la voix de Karen Cheryl… Désolé… (ou tant mieux pour nous…)

– Convertir le texte écrit dans le fichier « texte » en un phonème compréhensible par Mbrola

espeak -x -v mb/mb-fr4 -f texte > texte.pho

– Faire parler le serveur en lisant le phonème

mbrola -t 1.0 -e -C « n n2 » /opt/mbrola/fr4/fr4 texte.pho -.au | aplay

– Convertir la phrase lue par mbrola en un fichier Wav

mbrola -e -C « n n2 » /opt/mbrola/fr4/fr4 texte.pho texte.wav

(pour les options mbrola que j’utilise, t = la vitesse de lecture, voir la doc officielle)

Pour lire le wav en ligne de commande, mplayer est votre ami.

  • PULSEAUDIO ou le son en réseau

Voila la partie où j’ai passer le plus de temps.

Je souhaitais récupérer le son émis par mon serveur sur mon portable connecté en Wi-Fi.

Le premier serveur de son qui m’est venu a l’esprit fut bien sur Pulseaudio.

C’est là que les complications sont arrivées…

Pulseaudio peut fonctionner en multicast, comprendre que le son est diffusé dans tout le LAN, il peut même s’intégrer a Avahi (le mDNS type « Bonjour »).

Sauf que moi le multicast, j’aime pas ça (va comprendre Charles…) et qui plus est, j’ai un LAN segmenté par VLAN et centralisé par du Cisco, et la conf multicast sous Cisco, ca me fait mal au crâne 🙂

Donc, out le multicast, je veux de l’unicast TCP (bah oui, j’aime bien les trames réseaux bien proprettes 😀 )

L’installation de Pulseaudio sous Debian Lenny passe par un apt-get install tout simple (n’oubliez pas pulseaudio-utils)

Côté configuration sur le serveur Domotique :

srvdomotique:/etc/pulse# cat default.pa
#!/usr/bin/pulseaudio -nF
.nofail
load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
.fail
.ifexists module-hal-detect.so
load-module module-hal-detect
.else
load-module module-detect
.endif
### Load several protocols
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix socket="/tmp/.esd/socket"
.endif
load-module module-native-protocol-unix
load-module module-esound-protocol-tcp auth-anonymous=1
load-module module-native-protocol-tcp listen=192.168.43.100 auth-anonymous=1
load-module module-tunnel-sink server=192.168.8.201 sink_name=copie
load-module  module-combine sink_name=combined master="copie" slaves="alsa_output.pci_10de_3f0_alsa_playback_0"
.ifexists module-gconf.so
.nofail
#load-module module-gconf
.fail
.endif
### Automatically restore the volume of playback streams
load-module module-volume-restore
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-suspend-on-idle
.ifexists module-x11-publish.so
.nofail
load-module module-x11-publish
.fail
.endif
set-default-sink combined

Petite explication.

La ligne : « load-module module-native-protocol-tcp listen=192.168.43.100 auth-anonymous=1 » signifie que vous écoutez sur l’ip 102.168.43.100 et que vous autorisez les connexions anonymes (on va filter au niveau ACL du cisco)

La ligne : « load-module module-tunnel-sink server=192.168.8.201 sink_name=copie »

désigne le « client » qui va écouter les sons émis par le serveur domotique (en fait le client est le serveur domotique qui va émettre le son vers un serveur pulseaudio distant à l’ip 192.168.8.201…)

La ligne : « load-module  module-combine sink_name=combined master= »copie » slaves= »alsa_output.pci_10de_3f0_alsa_playback_0″ »

génère un « sink » (une destination audio si vous préférez), qui comprend ET le pc a l’adresse 192.168.8.201 (alias copie) ET la carte son du serveur Domotique.

Flux par défaut : set-default-sink combined

Ce qui veut dire que tout son émis doit être diffusé simultanément sur la carte son du serveur Domotique (je peux donc l’entendre par les enceintes branchées dessus) et sur les enceintes du PC client.

C’est clair ?

Sur le serveur Domotique, dont le système de son est géré par ALSA, je spécifie que tout les sons doivent être envoyés au démon PulseAudio grace au fichier /etc/asound.conf

srvdomotique:/etc# more asound.conf
pcm.pulse {
type pulse
}
 
ctl.pulse {
type pulse
}
 
pcm.!default {
type pulse
}
 
ctl.!default {
type pulse
}

Reste à lancer pulsaudio (ou par la commande pulseaudio -Cvvv pour voir ce qui se passe ou par la commande pulseaudio -D pour le daemoniser en arrière plan).

Les sons émis par votre serveur doivent être audible sur les enceintes de celui-ci.

Sur le PC client (mon portable en l’occurence), installation de pulseaudio normale, puis un default.pa comme suit :

#!/usr/bin/pulseaudio -nF
.ifexists module-hal-detect.so
load-module module-hal-detect
.else
load-module module-detect
.endif
.ifexists module-esound-protocol-unix.so
.endif
load-module module-native-protocol-unix
load-module module-esound-protocol-tcp auth-anonymous=1
load-module module-native-protocol-tcp listen=192.168.8.201 auth-anonymous=1
.ifexists module-gconf.so
.nofail
.fail
.endif
load-module module-volume-restore
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-suspend-on-idle
.ifexists module-x11-publish.so
.nofail
load-module module-x11-publish
.fail
.endif

Rien d’autre (pas de fichier /etc/asound.conf, pas de données dans client.conf)

Lancer pulseaudio sur le client puis lancer pulseaudio sur le serveur Domotique. Les sons émis par le serveur domotique arrive sur le pc portable (même dans KDE pour ma part…)

Oui, MAIS !!!

Le gros problème est que si le PC portable se connecte APRES le démarrage de PulseAudio sur le serveur Domotique et bien, cela ne fonctionne plus !!!!

J’ai passé des jours a chercher et je n’ai pas réussi a comprendre pourquoi le serveur Domotique ne voyait pas le portable se connecter… J’ai tourner dans tout les sens, impossible de le faire marcher comme cela donc si vous avez une solution, je suis preneur !!!

Mais je n’allais pas en rester la et donc pour réussir ce tour de force, j’ai décider de forcer l’enregistrement du pc portable sur le serveur son Domotique via quelques scripts.

Alors, un peu de compassion pour moi, je ne suis pas développeur et c’est sûrement très crado comme code mais au moins ça marche :-p

– Technique d’enregistrement d’un client PulseAudio via socket en Python.

Sur le serveur Domotique, on va faire tourner un petit serveur codé en Python qui écoute sur le port tcp 12345 :

srvdomotique:~# cat pulseserver.py
#!/usr/bin/python
import socket
import subprocess
import sys
import os
servsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 
try:
    servsock.bind(('',12345))
 
except socket.error:
        print "Relance Pulse"
        pidpulse = subprocess.Popen("ps acx | grep pulseaudio | awk '{print $1}'", shell=True, stdout=subprocess.PIPE)
        pid = pidpulse.stdout.read()
        print pid
        os.kill(int(pid), 9)
        pidpulse.stdout.close()
        subprocess.call(["pulseaudio -D"],shell=True)
        servsock.bind(('',12345))
 
servsock.listen(1)
while True:
sock,addr = servsock.accept()
echo = sock.recv(1024)
subprocess.call(["/home/scripts/enregistrement_station.sh"],shell=True)
sock.send(echo)
sock.close()

Quand le client se connecte, le serveur domotique lance le script enregistrement_station.sh :

#!/bin/bash
PIDPULSE=` ps acx | grep pulseaudio | awk '{print $1}'`
kill -9 $PIDPULSE
pulseaudio -D
sleep 2
mplayer /opt/sound/notify.wav
mbrola -t 1.1 -e -C "n n2" /opt/mbrola/fr4/fr4 /opt/mbrola/enregistrement_station.pho -.au | aplay

Dans /etc/rc.local, vous n’avez plus qu’a rajouter la ligne :
/cheminduscript/pulseserver.py &
pour le lancer au boot du serveur.

Côté PC portable, le script de connexion.sh :

#!/bin/bash
PIDPULSE=` ps acx | grep pulseaudio | awk '{print $1}'`
# On allume le haut-parleur a 80%
amixer -q set Master 80%,80%  unmute
if  test -n "$PIDPULSE"
then
echo "pulseaudio actif"
else
pulseaudio -D
fi
sleep 1
python /home/guiguiabloc/pulseclient.py
exit 0

Et le client en python (pulseclient.py)

#!/usr/bin/python
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = 'srvdomotique'
port = 12345
print 'Connexion sur ', host, port
client.connect((host, port))
client.close

Je vous le conçois, c’est bourrin…
Quand le portable lance le script « connexion.sh », il lance pulseaudio en local, se connecte au serveur domotique sur le port 12345 qui kill son pulseaudio et le relance, puis fait dire au serveur domotique une phrase annonçant l’enregistrement de la station.
Mais au moins ça marche…

Donc si vous avez d’autres solutions, je suis à votre écoute 😀

  • ZONEMINDER et xAP (avec un soupçon de SEC)

Dernière étape de mon travail, mon zoneminder.

ZoneMinder, c’est « vachement » bien, ça fait plein de truc par défaut mais il me manquait une fonction essentielle.

Quand l’on positionne ses caméras en mode « Modect », il détecte les mouvements dans la zone que vous avez définie et enregistre la séquence. Une fois achevée, il vous envoie un email pour vous prévenir d’un mouvement et vous donne le lien vers le « film ».

Super, mais entre le moment où ZoneMinder déclenche l’enregistrement, l’achève après un temps pré-défini (j’utlilise un buffer de 10 secondes avant et 30 secondes après), et vous envoie le mail, bah il se passe plusieurs secondes, voir minutes.

Ce que je voulais c’est que dès qu’un mouvement était détecté par la caméra, ZoneMinder me prévienne d’une manière ou d’une autre. Dans mon cas, en me l’annonçant de sa douce voix (via mbrola).

Ce n’est pas natif dans les fonctions de ZoneMinder et mon bonheur je l’ai trouvé (après moults recherches je vous l’avoue), chez xAP.

Pour résumer, xAP est un protocole open dédié a l’automatisation. C’est la première fois que j’en entendais parler et les fonctionnalités sont nombreuses et puissantes.

Et l’une de ses nombreuses fonctionnalités justement, c’est sa possibilité d’intégration avec ZoneMinder, via un script perl nommé ZMXAP.

En fait, au fin fond du WiKi Zoneminder, on trouve un article dessus :

http://www.zoneminder.com/wiki/index.php/Zmxap

Ni une ni deux, on se télécharge le bazar ici :

http://www.limings.net/xap/zmxap/zmxap-v0.9.tar.gz

La conf est trivial, juste a spécifier nohub=1 dans le zmxap.conf et surtout, pour le besoin que j’avais, générer un fichier de log avec la variable log_file = /tmp/zmxap.log

Car  zmxap est capable d’intéragir directement avec Zoneminder et donc de recevoir en temps réel les informations qui en découlent.

Petit test pour le vérifier :

On lance Zmxap.pl avec la variable du path :

/opt/scripts/zmxap/zmxap.pl -path=/opt/scripts/zmxap &

On passe la caméra en mode « Modect », on passe devant elle et on regarde ce qui se passe dans le fichier /tmp/zmxap.log

24.08.2010 19:32:08 [INFO] (main::loadMonitors): Loading monitors
######## in sendAlarmEvent
####### state=2 and cause=Motion
###### starting fetch of event_data
###### completed fetch of event_data
######## completed sendAlarmEvent
24.08.2010 19:36:03 [INFO] (checkState) Sous_Sol - initiating alarm state
######### completed sendTrackingEvent
24.08.2010 19:36:18 [INFO] (checkState) Sous_Sol - resuming idle state
######## in sendAlarmEvent
####### state=0 and cause=Motion
###### starting fetch of event_data
###### completed fetch of event_data

Magique !!!

ZMXAP a détecté immédiatement le passage (initiating alarm state) puis on voit l’enregistrement se faire.

Ne reste plus qu’a analyser ce fichier de log en temps réel pour remonter l’info.

Et qui a-t-il de mieux pour analyser un fichier de log temps réel ? hein ? Pourtant je vous en avez déjà parler :

http://blog.guiguiabloc.fr/index.php/2009/03/18/interception-des-erreurs-applicatives-dans-nagios-avec-sec-et-prelude-lml/

SEC bien sûr !!!

Allez hop, on se configure notre sec.conf :

type=single
ptype=RegExp
pattern=Sous_Sol(.+)alarm
desc=$0
action=shellcmd  /opt/scripts/AUDIO_alarme_soussol.sh

le script AUDIO_alarme_soussol.sh ne fait que lire une phrase disant « attention y’a un méchant monsieur au sous-sol » (ou autre chose hein…)

Ne reste qu’a lancer tout cela ensemble :

#!/bin/bash
/opt/scripts/zmxap/zmxap.pl -path=/opt/scripts/zmxap &amp;
/usr/local/bin/sec/sec.pl -conf=/usr/local/bin/sec/etc/sec.conf -input=/tmp/zmxap.log -log /var/log/sec.log &amp;

Et voilà, désormais, en plus d’enregistrer les mouvements détectés, ZoneMiner vous prévient immédiatement dès qu’il détecte un mouvement !

C’est pas beau ça ?

Voila un tour de ce que j’ai mis en oeuvre ses dernières semaines, j’avoue que pulseaudio m’a beaucoup coûter en temps, essayant de lui faire recharger sa configuration quand il voyait le portable mais sans succès.

En tout cas, désormais, tout fonctionne à merveille et après tout, c’est tout ce que l’on en attend.

Amusez vous bien 😀

Classé dans domotique, geekerie, linux | Taggé , , , , | 9 Commentaires