Christophe Nowicki

November 27, 2009

xPL Perl update script for Pachube

I’ve wrote a small update script for Pachube based on xPL-Perl.
This module is based on Beanz’s Net::Pachube module.
I use this script, for my pachube feed.

Setup

The setup is very simple on Debian GNU/Linux, at first you need the Net::Pachube module :
$ wget http://search.cpan.org/CPAN/authors/id/B/BE/BEANZ/Net-Pachube-0.01.tar.gz
$ tar xzf Net-Pachube-0.01.tar.gz
$ cd Net-Pachube-0.01
$ perl Makefile.PL
$ make
...
# make install

Note: the dh-make-perl method does not work, with this package ;-(

Then you can grab, my xpl-pachube script :

$ svn co http://svn.csquad.org/xpl-pachube/
..
# chmod +x xpl-pachube/xpl-pachube
# mv xpl-pachube/xpl-pachube /usr/local/bin

Run

You can start the xpl-pachube script in verbose this way :

$ xpl-pachube -key 52b37888404598851de -verbose -feed_id 1934 class=sensor device=cc128.01189.0.1

You need to change the -key and -feed_id arguments.

That’s all folks!

Filed under: Home automation,Programming — Tags:, , — cscm @ 23:29

October 23, 2009

xPL Automatic Speech Recognition with Julius

I’ve wrote a very small Perl module for interfacing my home automation Speech Recognition Engine based on Julius with the xPL Network.

The goal of this xpl-perl module, is to broadcast recognised speech.

I’ve described the ASR xPL schema on the project forum : ASR.BASIC Schema proposal

You need a working Julius installation running in monitor mode (listening on the network) and an xpl-perl setup.

Here is an sample command output :
$ julius -input file -C julian.jconf
...
Stat: server-client: socket ready as server
///////////////////////////////
/// Module mode ready
/// waiting client at 10500
///////////////////////////////

In others windows, you must run xpl-asr-julius and xpl-logger.
When you speak or send a wav file to Julius, the reconised text is broadcasted on the network :
### read waveform input
enter filename-> test.wav
Stat: adin_file: input speechfile: test.wav
STAT: 180003 samples (3.75 sec.)
STAT: ### speech analysis (waveform -> MFCC)
STAT: 00 _default: 17 generated, 17 pushed, 6 nodes popped in 1123

xpl-logger output :
10.0.0.242:53922 [xpl-trig/asr.basic: bnz-julius.nux -> * - <s> éteindre lumière chambre </s>]

Installation

The setup is very simple on Debian GNU/Linux. Just fallow thoses instructions :
$ wget /wp-content/contrib/xpl-asr-julius/xPL-ASR-Julius-0.01.tar.gz
$ tar xzf xPL-ASR-Julius-0.01.tar.gz
$ dh-make-perl xPL-ASR-Julius-0.01
$ cd xPL-ASR-Julius-0.01
$ dpkg-buildpackage -b
# dpkg -i ../libxpl-asr-julius-perl*.deb

That’s all !

Filed under: Home automation — Tags:, , , — cscm @ 15:26

September 26, 2009

Archivage des messages xPL dans une base de données

Voici la procédure pour archiver les messages de votre réseau xPL dans une base de données MySQL.

L’objectif

Beanz, l’auteur du projet xpl-perl a supprimé la fonctionnalité du projet dans la version 0.08.

Cette fonctionnalité répond à un besoin très spécifique.
Archiver TOUS les messages dans une base de données MySQL demande beaucoup de ressources.
Sur mon petit réseau domotique, j’ai déjà plus de 25 messages par minute.

Ce qui produit une base de données importante avec 100 000 entrées par semaine, soit 500 000 par mois, 6 000 000 par an.

Et la taille de la base de données fait dans les 50 Mo par semaine, soit 250Mo par mois, 3Go par an.

Donc pour stocker ces données vous devez en avoir vraiment besoin. C’est mon cas, car :

  • Je veux conserver la consommation électrique exact de chaque appareil ;
  • Utiliser des optimisations à l’aide d’un réseau de neurones.

Installation

Vous devez disposer d’un réseau xPL fonctionnel et d’une installation de xpl-perl.

Programme

Nous allons récupèrer le code des modules directement dans le svn.


# cd /usr/share/perl5/xPL
# wget http://www.xpl-perl.org.uk/export/892/xpl-perl/branches/r0.08/lib/xPL/SQL.pm
# sed -i -e 's#/etc/xpl-perl/db.config#/etc/xplperl/db.config#' SQL.pm
# cd /usr/bin
# wget http://www.xpl-perl.org.uk/export/892/xpl-perl/branches/r0.08/bin/xpl-sql-logger
# chmod +x xpl-sql-logger
# apt-get install libclass-dbi-loader-perl libdatetime-perl
# cd /etc/xplperl
# cat < db.config
dsn=dbi:mysql:xpl:localhost
user=xpl
password=secret
EOF
#

Base de données

Une fois que vous avez installé le programme, il est nécessaire de configurer la base de données.

Pour cela vous devez créer un utilisateur xpl et une base de données xpl sur votre serveur MySQL.
Ensuite vous créer les tables de la base de données à l’aide des requêtes SQL suivantes :

CREATE TABLE body (
id int NOT NULL auto_increment,
body varchar(1500) default NULL,
PRIMARY KEY (id),
KEY body_idx (body(1000))
);
CREATE TABLE elt (
id int NOT NULL auto_increment,
name varchar(16) default NULL,
value varchar(128) default NULL,
PRIMARY KEY (id),
KEY name_idx (name)
);
CREATE TABLE msg (
id int NOT NULL auto_increment,
time int default NULL,
usec int default NULL,
type char(8) default NULL,
source varchar(34) default NULL,
target varchar(34) default NULL,
class varchar(15) default NULL,
incomplete int default NULL,
body int default NULL,
PRIMARY KEY (id),
KEY class_idx (class),
KEY time_idx (time,usec),
KEY type_idx (type),
KEY body_idx (body)
);
CREATE TABLE msgelt (
id int NOT NULL auto_increment,
msg int NOT NULL,
elt int NOT NULL,
PRIMARY KEY (id),
KEY msg_idx (msg),
KEY elt_idx (elt)
);

Lancement et recette

Vous pouvez ensuite lancer le programme en ligne de commande :
$ xpl-sql-logger
Vous pouvez ensuite vérifier que cela fonctionne dans la base de données :
mysql> SELECT * FROM `msg` ORDER BY id DESC LIMIT 3;
+---------+------------+--------+----------+----------------+--------+--------------+------------+
| id | time | usec | type | source | target | class | incomplete |
+---------+------------+--------+----------+----------------+--------+--------------+------------+
| 7711941 | 1253948224 | 252455 | xpl-trig | bnz-ccost.milk | * | sensor.basic | 0 |
| 7711931 | 1253948224 | 211170 | xpl-trig | bnz-ccost.milk | * | sensor.basic | 0 |
| 7711921 | 1253948224 | 130241 | xpl-trig | bnz-ccost.milk | * | sensor.basic | 0 |
+---------+------------+--------+----------+----------------+--------+--------------+------------+
3 rows in set (0.00 sec)

Lancement automatique

Vous pouvez lancer automatiquement le programme à l’aide de daemontools en plaçant le programme dans le répertoire /etc/services de la manière suivante :

# cd /etc/xplperl/service
# cp -r xpl-hub xpl-sql-logger
# cd xpl-sql-logger
# cat < run
#!/bin/sh
exec 2>&1
exec setuidgid xplperl envdir ./env softlimit -d300000 /usr/bin/xpl-sql-logger
EOF
# cd /etc/service
# ln -s /etc/xplperl/service/xpl-sql-logger/
# ps auxww | grep xpl-sql-logger
root 3306 0.0 0.0 1620 332 ? S Sep22 0:00 supervise xpl-sql-logger
xplperl 23943 1.3 0.6 16944 12952 ? S 08:20 0:37 /usr/bin/perl -w /usr/bin/xpl-sql-logger

Surveillance de l’archivage

monit logo Le système fonctionne très bien. Par contre, j’ai rencontré quelques problèmes au bout d’une ou deux semaines le programme arrête d’archiver les données dans la base, il faut donc le relancer.
La solution la plus simple et de relancer le script à l’aide d’un cron et monit

.
Voici mon crontab :

*/1 * * * * echo "SELECT NOW() - FROM_UNIXTIME(time) FROM msg ORDER BY id DESC LIMIT 1;" | mysql -hlocalhost -uxpl -psecret -s xpl > /tmp/xpl-sql-logger

Voici ma configuration pour monit dans le fichier /etc/monit.d/xpl-sql-logger :

check file xpl-sql-logger with path /tmp/xpl-sql-logger
if match "^[0-9]{1,2}" then stop
stop program = "/usr/bin/killall -r xpl-sql-logger"

Exploitation des données

Pour exploiter les données, je suis en train d’écrire des gadgets pour Portaneo (P.O.S.H) à afin de pouvoir afficher les données sous forme de graphiques ;-)

Filed under: Debian,Home automation — Tags:, , , — cscm @ 11:44

August 11, 2009

xPL Text-to-Speech module

I’ve wote an Text-to-Speech module for xPL Perl based on eSpeak and the Speech::eSpeak Perl module.

The xPL TTS.BAISC schema is very basic, but suffisent for my text-to-speech needs.

Setup on Debian GNU/Linux

You should install the fallowing packages with apt :
# apt-get install libespeak-dev dh-make-perl espeak-data devscripts

And build the Perl module :
# cd /usr/src
# wget http://search.cpan.org/CPAN/authors/id/H/HG/HGNENG/Speech-eSpeak-0.3.tar.gz
# tar xzf Speech-eSpeak-0.3.tar.gz
# dh-make-perl Speech-eSpeak-0.3
# cd Speech-eSpeak-0.3
# debuild
# dpkg -i dpkg -i ../libspeech-espeak-perl*

Get my source code :
# wget http://www.csquad.org/wp-content/contrib/eSpeak.pm -O /usr/share/perl5/xPL/Dock/eSpeak.pm
# wget http://www.csquad.org/wp-content/contrib/xpl-tts -O /usr/bin/xpl-tts
# chmod +x /usr/bin/xpl-tts

Usage exemples

Launch the xpl-tts program :
$ xpl-tts -espeak-verbose -espeak-voice-language en -espeak-voice-gender 2 -espeak-voice-age 42
Then, send an xpl command on the network :
$ xpl-sender -m xpl-cmnd -c tts.basic speech="xPL rocks everything"

You should hear the synthesized voice.

And Voila ;-)

Bugs and evolutions

I will submit this module to the xpl-perl project and try to implement MBROLA project support. Because I’ve got a more humain voices.

Filed under: Home automation — Tags:, , , — cscm @ 17:17

February 11, 2006

Retour d’expérience sur la personnalisation du logiciel libre de gestion d’incident « Request Tracker »

Après plusieurs mois de travail sur la personnalisation de cet outils pour un client, j’ai le plaisir de vous presenter un article qui décrit notre travail.
Mais tout d’abord une rapide présentation du logiciel.

Request Tracker

RT est un logiciel libre de gestion d’incident, en anglais ticketing, il permet la prise en charge des demandes client. Lorsqu’un problème survient chez un de nos clients (plantage serveur, coupure de service, etc…) celui-ci envoie un mail ou bien téléphonne au support pour signaler l’incident.
Cet incident donne lieu à un ticket qui sera pris en charge par le support technique.
Grace à ce système :

  • Les clients peuvent suivre en temps réel, la résolution de l’incident
  • Communiquer avec le support
  • Le support facture les interventions
  • L’ensemble des interventions sont archivées.

Nous utilisons ce système chez Easter-eggs depuis près de 3ans avec succés et nous en sommes très content, comme beaucoup d’autres.
La mise en place de système est assez complexe et nécessite de bonnes compétances en administration système et en programmation Perl ( si vous voulez modifier l’outils pour l’adapter aux besoins spécifiques de votre entreprise).
Pour vous aider dans l’installation de l’outil, un article est paru dans le Linux Magazine France de ce mois-ci (Février 2006), mais celui-ci ne parle pas de la personnalisation de l’outils.

L’application de Suivi Qualité

L’Application de Suivi Qualité développée par Easter-eggs à partir de RT offre la possibilité de :

  • s’interfacer avec l’annuaire LDAP de l’entreprise ;
  • importer les bases de données d’un outil existant ;
  • effectuer des recherches dynamiques simplifiées ;
  • réaliser des imports CSV à partir d’un ERP ;
  • avoir une interface dynamique sans rechargement avec Javascript, méthodologie AJAX;
  • personnaliser les emails ;
  • gérer de manière automatisée les relances des tâches échues ;
  • extraire des statistiques d’activité.

Le retour d’expérience sur la modification

Mon article est disponible au format PDF à l’adresse suivante :

Retour d’expérience sur la personnalisation du logiciel libre de gestion d’incident « Request Tracker »

Filed under: Work — Tags:, — cscm @ 10:20

January 12, 2006

Gestion des exceptions SOAP en Perl avec les module SOAP::Lite et Error

Après une longue journée de travail, j’ai enfin réussi à faire fonctionner correctement le système de gestion d’exception de SOAP::Lite avec le module Error. Tout d’abord quelques explications.

Système de gestion d’exception

Tout programme en exécution peut être sujet à des erreurs, pour lesquels des stratégies de détection et de réparation sont possibles. Ces erreurs ne sont donc pas des bogues des programmes, mais des conditions particulières, on parle aussi de conditions exceptionnelles ou exceptions dans le déroulement normal d’une partie d’un programme.

Module Perl Error

Le module CPAN Error permet de gérér les exceptions en Perl. Il propose une interface objet semblable à celle disponible dans des langages comme Java ou bien C#. Le module repose sur la fonction die du langage.

SOAP::Lite

Le projet SOAP::Lite permet de prendre en charge l’ensemble des protocoles lier aux Web Services (SOAP, WSDL et UDDI). L’ensemble des fonctionnalitées offertes sont extrèment riches et puissantes. Vous pouvez aussi bien faire un serveur qu’un client en Perl et vous interfacer avec des Service écrit dans de nombreaux autres langages.

Entre la théorie et la pratique …

L’ensemble des interactions sont décrites dans les spécifications des protocoles de Web Services. Mais comme présque toujours en informatique, chaque constructeur, langage ou implémentation apporte son lot de spécificitées.

Dans le cas du langage Perl, les deux principaux sont l’absence :

  • de typage
  • d’un système de gestion d’exception

Le permier problème se controurne à l’aide de la déclaration des type dans un fichier WSDL.
Pour le second, j’ai eu un peu plus de mal avant de trouver la solution.

A propos du code source de SOAP::Lite

Ce n’est vraiment pas un exemple à suivre :

  • très peu de commentaires dans le code
  • seul fichier de 5000 lignes
  • le mode de debug trace n’est pas assez verbeux
  • on se demande souvent si l’auteur du module n’a pas coder sous l’imfluence de certaines drogues

L’anomalie de fonctionnement

Lorsqu’une exception est levée à l’aide de la fonction throw dans un module Perl elle créer un objet pour indiquer des informations sur le contexte de l’erreur. L’objet le plus simple est Error::Simple

sub foo {
   throw Error::Simple( "A simple error");
}

Il est possible de créer vos propres objets en utilisant l’héritage en utilisant l’objet Error comme base.

La framework SOAP::Lite détourne la fonction die et renvoie une exception SOAP qui contiens un objet. La problème est que cela ne fonctionne pas correctement :

 SOAP Fault :
        Fault String : Application error
        Fault Detail :  {
          'Error__Simple' => {
                             '-file' => 'Demo.pm',
                             '-text' => 'A simple error',
                             '-package' => 'Demo',
                             '-line' => '9'
                           }
        };

        Fault Actor  : http://localhost:4242/

Le contenu de Fault Detail n’est pas un objet MAIS une table de HASH.
De plus un message d’erreur du côte du serveur vous indique qu’il y’a visiblement un problème avec la serialisation :

 Use of uninitialized value in sprintf at /usr/share/perl5/SOAP/Lite.pm line 814.
Cannot encode 'namesp1:something' element as 'hash'. Will be encoded as 'map' in  stead

Après quelques heures de tatonnement et de recherche dans le code source de SOAP::Lite, j’ai trouver la source du problème.

Les attributs du module Error contiennent tous un préfixe qui fait échouer la serialization :

$VAR1 =  bless( {
        '-file' => '...',
        '-text' => '...',
        '-package' => '...',
        '-line' => '...'
        }, 'BadError')

La fonction résponsable de ce bug est SOAP::Serializer::encode_hash.
Une expression régulier empeche la serialisation d’un caractère ‘-‘ dans le flux XML.

J’ai donc déciser de supprimer le caractère ‘-‘ dans le nom des attributs à l’aide du boût de code suivant :

sub encode_hash {

my($self, $hash, $name, $type, $attr) = @_;

  while(my ($k, $v) = each (%$hash))
  {
    if ($k =~ m/^-/)
    {
        $k =~ s/^-//;
        $hash->{$k} = $v;
        delete $hash->{'-'.$k};
    }
  }

  if ($self->autotype && grep {!/$SOAP::Constants::ELMASK/o} keys %$hash) {

Et Voilà !

Cela fonctionne enfin correctement :

 SOAP Fault :
        Fault String : Application error
        Fault Detail :  {
                             'detail' => bless ( {
                             '-file' => 'Demo.pm',
                             '-text' => 'A simple error',
                             '-package' => 'Demo',
                             '-line' => '9'
                           }, 'Error::Simple')
        };

        Fault Actor  : http://localhost:4242/

Je vais contacter l’auteur du module pour trouver une solution plus propore ;0)
Mais en attendant celle-ci fonctionne correctement.

Filed under: Programming — Tags:, , — cscm @ 21:20

November 26, 2005

Génération dynamique de fichiers WSDL avec Perl

Dans le cadre de mon travail, je devais rendre accesible via des Web Services un ensemble de modules écrits en Perl.

Pour que les interfaces d’un module soient accessible via SOAP, il faut les décrire à l’aide du langage WSDL.

Le format WSDL est basé sur XML, il est relativement difficile de le comprendre et encore plus de l’écrire à la main.
C’est pour cette raison que la plupart des langages de programmation proposent des outils de géneration automatique.

Le principale problème que l’ont peut rencontrer avec ce genre d’outils est le manque de contrôle.

Pour palier à ce problème, Perl propose une solution remarquable : décrire l’interface à l’aide de commentaires directement dans le code.

Effectivement à l’aide du module Pod::WSDL, il est possible d’extraire les informations nécessaires pour créer le fichier de déscription d’interface.

Par exemple :

=begin WSDL

_IN $bar $string description du paramètre
_RETURN $string
_FAULT Error::Simple Le type d'éxception déclancher en cas d'erreur
_DOC description rapide du fonctionnement de ma fonction

=cut

sub foo ($) {
my $bar = shift;
return $bar;
}

Ensuite, il ne reste plus qu’à charger le module précédant et extraire les informations pour produire le fichier WSDL, à l’aide du bout de code suivant:

use Pod::WSDL;

my $pod = new Pod::WSDL(
source => 'My::Server',
location => 'http://localhost/My/Server',
pretty => 1,
withDocumentation => 1);

print $pod->WSDL;

Celui-ci vous affiche le fichier WSDL, directement sur la sortie standard.

Les fichiers produits par Pod::WSDL sont conformes aux spécifications et fonctionnent parfaitement.
Je les ai testé avec SOAP::Lite et le framework Apache Axis.

Nous avons une jolie solution pour créer des fichiers WSDL directement lors de l’installation de nos modules.

Néanmoins j’ai voulu pousser le concept de génération dynamique un peu plus loin.

Tout simplement parce que mon interface SOAP est séparée des modules qu’elle met à disposition (dans deux paquets différents).

Dans Web Services, il y a la notion de Web. J’ai donc mis à contribution le framework Mason, qui est un outil de template permetant de faire des sites web dynamiques en Perl.

Celui-ci dispose deux fonctionnalités intéressantes :

  • un système de cache ;
  • un système de gestion de page non disponible.

Le système de gestion de page non disponbile, permet de créer des pages web dynamiquement en fonction de l’url demander.

Le fichier dhandler suivant permet de créer dynamiquement un fichier WSDL en fonction du nom du module Perl:

< %once>
use Pod::WSDL;
use strict;
< %once>
< %init>
my $arg = $m->dhandler_arg;
$arg =~ s/\.wsdl//;
my $pod;

eval {
$pod = new Pod::WSDL(
source => $arg,
location => 'http://localhost/soapEndPoint',
pretty => 1,
withDocumentation => 0
);
};
if ($@) {
return 404;
}
$m->out($pod->WSDL);
< /%init>

Par exemple pour récupèrer le fichier WSDL pour le module Test, il suffit d’aller sur l’url : http://localhost/Test.wsdl.

L’opèration de géneration est rélativement rapide, mais dans le cas d’un service fortement solicité, il faut mettre en place un système de cache, comme celui décrit dans la documentation de Mason : DATA CACHING

Voilà

Filed under: Programming — Tags:, , — cscm @ 22:22

Powered by WordPress