SARAH gère le frigo

Parmi les sujets récurrents sur la communauté Google+ il y a la gestion du réfrigérateur ou des courses par SARAH. Voici un petit aperçu de ce qu’il est possible de faire.

Base de donnée

La première étape consiste à persister et retrouver des données. Plutôt que d’utiliser une usine à gaz SQL j’ai mis en place NeDB qui est une petite base NoSQL inMemory. Et qui fonctionne comme MongoDB:

[crayon]
exports.init = function(sarah){
var Datastore = require(‘./lib/nedb’);
var path = __dirname + ‘/frigo.db’;
db = new Datastore({ filename: path});
db.loadDatabase(function (err) { … });
}
[/crayon]

On se branche sur le hook init() de manière à charger la base au chargement du plugin.

[crayon]
var save = function(data){
db.update({‘name’: data.name }, data, { upsert: true },
function(){ … });
}
[/crayon]

[crayon]
var remove = function(data){
db.remove({‘name’: data.name }, {}, function(){ … });
}
[/crayon]

Ensuite les méthode save() et remove() permettent une mise à jour d’un objet de la base.

Grammaire XML

Lors de chaque mise à jour de la base il faut mettre en cache la liste des produits (pour ne pas avoir à faire un appel asynchrone)

[crayon]
var cacheProducts = function(){
db.find({ name: {$gt:’1′} }, function(err, docs){ products = docs;});
}
[/crayon]

Puis réécrire le fichier XML
[crayon]

out.action=new Object();
Sarah

ajouteout.action.add= »true »;
enlèveout.action.add= »false »;


Nutellaout.action.product= »Nutella »;

out.action._attributes.dictation= »true »;

dans les courses
à la liste des courses
aux courses

out.action._attributes.uri= »http://127.0.0.1:8080/sarah/frigo »;

[/crayon]

[crayon]
var rewriteXML = function(){
var file = __dirname + ‘/frigo.xml’;
var xml = fs.readFileSync(file,’utf8′);

var replace = ‘§ –>n’;
for(var i = 0 ; i < products.length ; i++){
replace += ' ‘+products[i].name+’out.action.product= »‘+products[i].name+’ »;n’
}
replace += ‘<!– §';

var regexp = new RegExp('§[^§]+§','gm');
var xml = xml.replace(regexp,replace);
fs.writeFileSync(file, xml, 'utf8');
}
[/crayon]

En gros un marqueur permet de déterminer l'endroit ou chercher/remplacer les éléments de la grammaire.

Front End

Du côté Front End, il faut créer une page HTML composée de la liste des produits et d’un formulaire d’ajout / modification qui appelera les fonction qu’on vient de créer.

Actions

Enfin il faut développer la fonction principale des plugins pour aiguiller vers les actions à faire:

  1. Ajouter un élément à la liste
  2. Enlever un élément à la liste
  3. Lire les éléments de la liste
  4. Ajouter un élément à la base et à la liste

[crayon]
exports.action = function(data, callback, config, SARAH){

// 3. List courses
if (data.query){
var tts = "Voici la liste des courses: " + shopping.join(‘, ‘) + ‘.’;
return callback({‘tts’ : tts});
}

if (data.dictation){

// 4.1 Parse
var product = parse(data.dictation);

// 4.2 Save to database
save({name : product, tags :  », description :  »});
callback({‘tts’ : "Très bien j’ajoute " + product + " dans la base."});

// 4.3 Question
return ask(product);
}

// Check product
if (!data.product) return callback();

// 1 & 2 Add or Remove product
var tts = shop(data.product, !data.add);
callback({‘tts’ : tts});
}
[/crayon]

La fonction ask(product) utilise AskMe pour interroger l’utilisateur si il faut ajouter le produit aussi à la liste de course.

[crayon]
var ask = function(product){
SARAH.askme(« Est ce que j’ajoute aussi « +product+ » aux courses ? », {
« oui » : « true », « non » : « false »
}, 0, function(answer, end){

if (answer == ‘true’){ SARAH.speak(shop(product)); }
else { SARAH.speak(‘Ok tanpis.’); }
end();

});
}
[/crayon]

Conclusion

Voici le squelette d’un plugin qui permet de gérer une petite base de donnée de produit, réécrire son XML, gérer une liste de produit…

Pour aller plus loin il faudrait:

  • Utiliser le moteur de règle pour forwarder la liste de course par mail ou pushover
  • Créer une portlet des courses
  • Gérer le stock du frigo
  • Etre un peu plus prédictif

Le plugin se télécharge ici, il y a un petit patch à appliquer.

  1. J’étais en train de faire un peu le même style de boulot ses dernier jours mais je me suis retrouvé confronter au problème de reconnaissance des garbadge….
    En gros, pour ajouter un item dans la liste il me fallait, parfois, répéter 5 ou 6 fois la phrase -__- Quand je voyais ce qui passait dans la console de debug au niveau du dictation ça n’avait rien à voir (et ça quand sarah lançait le plugin…..)
    Pourtant je suis à moins d’1 mêtre du kinecte u_u

    J’aime

    1. Ouai c’est la reco Google qui est vraiment pas top, j’ai vu que le projet que j’utilise a été porté sur GitHub donc peut être que des choses ont été améliorée

      J’aime

      1. Je jetterais un oeil à la source histoire de voir si il y a un truc que j’aurais loupé, amis dans l’état, mon plugin est en stand by, parce que pas utilisable….

        J’aime

Répondre à platypusgeek Annuler la réponse.