11/07/2017

Qu'est-ce qu'un MAS ou système multi-agent ?

Qu'est-ce qu'un MAS ou système multi-agent ?

D'après le document Object-Oriented Simulator of Multi-Agent System for Temporally Rich Domains un MAS peut être défini ainsi :
MAS=(E, O, A, R, Op, LoU), (voir Ferber J. Multi-Agent Systems: An introduction to Distributed Artificial Intelligence, Adison-Wesley, 1999 )
where E is an environment, i.e. space which has a volume. In our experimental environment, E is a dynamical scene – a space with defined metrics. By knowing physical characteristics of objects (velocity, acceleration), and because of metric space, a temporal component can be assigned to each action. O is a set of objects situated in E. The objects are movable and/or stationary and they can be perceived by agents. A is an assembly of agents. Agents may be represented as specific objects (A⊆O) representing active entities with or without sensors. R is a set of temporal and some spatial relations among objects and agents. Op is a set of operations of agents, such as: perceiving, transforming and manipulation of objects. LoU is a set of, socalled, laws of the universe, which are common for the environment E.

SmagYun


Objectif :

 Console Multi-joueurs OpenSource : SMAGYUN


pour une autre vue du projet SmagYun, basée sur le projet Smag0,
- faites un tour ici : http://smag-cece4.firebaseapp.com/?search=SmagYun (attention cette interface met du temps à charger, la page reste blanche un bon moment )
- ou téléchargez les informations au format json à cette adresse
- vous pouvez aussi effectuer votre requête Sparql sur le endpoint https://rdf-smag0.rhcloud.com/ds/query
- requête pouvant être de la forme :
 SELECT * FROM <http://smag0.blogspot.fr/SparqlUpdate> WHERE { { <http://smag0.blogspot.fr/NS#SmagYun> ?Predicat ?Objet} UNION { ?Sujet ?Predicat <http://smag0.blogspot.fr/NS#SmagYun>  } }

pour commander une carte déjà configurée, ou poser des questions : twitter @DFaveris


Nécessite :

- Une carte Arduino Yun ou équivalent
- une carte micro-sd, 2Go (ou plus)

  1. Proposant 1 réseau local(isé) indépendant par défaut.
  2. Connectable à 1 réseau WiFi ou Ethernet existant.
  3. Nombre de participants illimité (limite inconnue à ce jour).
  4. Plateforme Web -> chat localisé avec socket.io, applications / jeux en javascript, python, unity, phazer.io, html5, p5js, threejs, babylonjs...
  5. NodeJs et socket.io pour synchronisation.
  6. Interraction Réel / Virtuel (connectique Arduino : capteurs, moteurs, led, boutons...)
  7. Mobile : sur batterie ou chargeur de téléphone (5 V)
  8. Micro-sd pour le stockage

Pourquoi Lininoio ?


L'avantage d'utiliser Lininoio est qu'il rend accessible les Pins Arduino (en raison de la polémique qui tourne actuellement autour d'Arduino, je me permettrait ici d'insérer deux liens, sans commentaire : http://www.arduino.org/ https://www.arduino.cc/ ) depuis le système d'exploitation Linux. Il n'est donc nul besoin d'écrire un programme Arduino, ce qui limite les environnements, l'environnement Arduino étant de plus, limité en terme de programmation.
Nous allons préférer utiliser NodeJs en raison de la multitude de modules existant, et de sa compatibilité avec tout types de navigateur, pc, mobile...




SmagYun utilise : 


  1. Lininoio : http://www.linino.org/tag/lininoio/
    Image à télécharger : http://download.linino.org/linino_distro/lininoIO/latest/lininoIO-generic-linino-yun-squashfs-sysupgrade.bin
  2. IMPORTANT : copier le programme Arduino "YunSerialTerminal" + réglez le moniteur Arduino à "Nouvelle ligne" et "115200 bauds" ), ceci peut faciliter la récupération de la carte Yun en cas d'imprévu.
  3. 'sysupgrade'  pour remplacer l’intégralité des fichiers de la carte par ceux de l'image :
    http://www.arduino.org/learning/tutorials/advanced-guides/how-to-upgrade-an-old-arduino-yun-or-yun-mini-to-linino (avec l'image lininoio) ou https://www.arduino.cc/en/Tutorial/YunSysupgrade (avec une autre image )
    copier l'image téléchargée sur la carte micro-sd, avec putty placez vous dans le répertoire où vous avez placé l'image, ce devrait être dans /mnt/sda1 (l'emplacement de la carte micro-sd) et lancer la commande :
    ```
    sysupgrade -v -n lininoIO-generic-linino-yun-squashfs-sysupgrade.bin

    ```
Sur un Windows 10, vous aurez besoin de 'WinScp' et de 'putty'.


CONFIGURATION DE LA CARTE : 


Après l'installation de la nouvelle image, connectez votre ordinateur Windows sur le Wifi "Arduino Yun".
Dans votre navigateur (Internet Explorer / Edge / Chrome / Firefox / Safari), vous devriez trouver à l'adresse http://192.168.240.1 la page d'accueil de la carte Arduino Yun. Le mot de passe est 'arduino' mais il vous faudra,
 ne pas oublier,
 de le changer,
 pour plus de sûreté.

On peut à tout moment se connecter la carte et la configurez  pour qu'elle se connecte au réseau Wifi et puisse télécharger programmes et mise à jour. Dans ce cas, la carte prendra une adresse IP sur votre réseau Wifi habituel, vous devrez retrouver cette adresse, on en aura besoin plus tard. la suite de la procédure nécessitera cette connexion.


Grâce à 'putty', vous pourrez interagir avec le système Linux en utilisant 'ssh root@192.168.240.1' depuis le réseau Wifi "Arduino Yun", ou sur la nouvelle adresse IP.
'Winscp' réglé en mode 'SCP' nous servira pour transférer des fichiers vers la carte plus facilement. Ah oui, à ce sujet, n'oubliez pas de modifier les préférences/Editeur de 'WinScp' pour lui demander d'ouvrir les fichiers qu'il télécharge directement dans votre éditeur préféré (Notepad ++ ).


PREMIERE COMMANDE : 


- connectez-vous à la carte avec putty  (192.168.240.1 en ssh, port 22 , utilisateur : root / arduino )
vous devriez voir apparaître la version de système d'exploitation installée : 
BusyBox v1.19.4 ( 2016-06-10 ....)
- pour en savoir plus sur la version de Linino installée, tapez lininoio -v.
moi j'ai en retour : 
DISTRIB_ID="Linino"
DISTRIB_REVISION="223d5a8"
BUILD_DATE="2016-06-01"

Le deuxième avantage de Linino, est de faciliter le déplacement du système Linux, gestionnaire de la carte, sur la carte micro-sd, j'ai lu, mais pas tout compris, que la carte Arduino Yun avait un nombre limité d'écritures, limitant sa durée de vie et qu'il vallait mieux écrire sur la carte sd que sur la mémoire de la carte,...
Pour cela, on utilise la commande " overlay-only -i". Ceci permet de formater la carte sd et de déplacer le système sur cette carte, ou de revenir en arrière.

NB : Pour les installations (lininoio, ide-linino-lib, node, socket.io, expres...), la carte doit être connectée à internet via la procédure décrite ci -dessus.

Après l'installation du système sur la carte, lançons Lininoio, la partie qui permet la connexion entre le système Linux et les pins Arduino, via la commande : 'lininoio start'. Si lininoio ne se lance pas, installez https://github.com/ideino/ideino-linino-lib au moyen d' "opkg", le programme d'installation de packages pour les système basés sur OpenWrt.
Je n'ai pas encore tout compris ce qui se passe à ce moment, mais ceci va remplacer le fichier 'YunSerialTerminal.hex' présent dans la partie Arduino, par un autre 'Bathos.hex' (https://github.com/ideino/ideino-linino-lib , http://www.linino.org/forums/topic/bathos-mods/ https://github.com/linino/bathos-mcuio, https://github.com/linino/bathos-mcuio/blob/atmega32u4/doc/bathos.in) et créer les dossiers /sys/class/pwm/pwmchip0 que l'on pourra utiliser directement depuis nodejs, aussi facilement que si l'on écrivait dans des fichiers...


Il convient à ce stade, généralement, d'installer node, socket.io et express
- opkg install node
- opkg install node-socket.io
- opkg install express

((> nodejs version 0.10.25 -> à voir pour upgrade possible avec Linino V2 (nodev6) 

pour connaitre la version de Linux installée : 
root@arduino:~# uname -a
Linux arduino 3.3.8 #1 Thu Jun 2 12:28:33 CEST 2016 mips GNU/Linux



PERSONNALISATION DE LA CARTE.


La personnalisation la plus importante à prendre en compte, la page web d'accueil de la carte (http://192.168.240.1 en mode hotspot)

Déplacement d'OSJS sur le port 81 : 

mon fichier /etc/config/uhttpd

# Server configuration
config uhttpd main

# HTTP listen addresses, multiple allowed
list listen_http 0.0.0.0:80
# list listen_http [::]:80

# HTTPS listen addresses, multiple allowed
list listen_https 0.0.0.0:443
# list listen_https [::]:443

# Server document root
# option home /osjs/dist
option home /www

# Reject requests from RFC1918 IP addresses
# directed to the servers public IP(s).
# This is a DNS rebinding countermeasure.
option rfc1918_filter 0

# Maximum number of concurrent requests.
# If this number is exceeded, further requests are
# queued until the number of running requests drops
# below the limit again.
option max_requests 2

# Certificate and private key for HTTPS.
# If no listen_https addresses are given,
# the key options are ignored.
option cert /etc/uhttpd.crt
option key /etc/uhttpd.key

# CGI url prefix, will be searched in docroot.
# Default is /cgi-bin
option cgi_prefix /cgi-bin

# List of extension->interpreter mappings.
# Files with an associated interpreter can
# be called outside of the CGI prefix and do
# not need to be executable.
# list interpreter ".php=/usr/bin/php-cgi"
# list interpreter ".cgi=/usr/bin/perl"

# Lua url prefix and handler script.
# Lua support is disabled if no prefix given.
# option lua_prefix /luci
# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua

# CGI/Lua timeout, if the called script does not
# write data within the given amount of seconds,
# the server will terminate the request with
# 504 Gateway Timeout response.
option script_timeout 60

# Network timeout, if the current connection is
# blocked for the specified amount of seconds,
# the server will terminate the associated
# request process.
option network_timeout 30

# TCP Keep-Alive, send periodic keep-alive probes
# over established connections to detect dead peers.
# The value is given in seconds to specify the
# interval between subsequent probes.
# Setting this to 0 will disable TCP keep-alive.
option tcp_keepalive 1

# Basic auth realm, defaults to local hostname
# option realm OpenWrt

# Configuration file in busybox httpd format
# option config /etc/httpd.conf


# Certificate defaults for px5g key generator
config cert px5g

# Validity time
option days 36500

# RSA key size
option bits 1024

# Location
option country CH
option state Zug
option location Zug

# Common name
option commonname DogHunter
config uhttpd secondary
    list listen_http 0.0.0.0:81
    option home /osjs/dist


déplacement du 'Document Root ' :
# Server document root
# option home /osjs/dist
option home /www

et ajout d'un deuxième port d'écoute sur le port 81 sur lequel on envoie l'ancienne page d'accueil : 
config uhttpd secondary
    list listen_http 0.0.0.0:81
    option home /osjs/dist 


Le serveur web correspondant à l'adresse http://192.168.240.1 est maintenant configuré sur le répertoire /www .

Osjs se trouve à l'adresse http://192.168.240.1:81 alors que la page par défaut est accessible à l'adresse http://192.168.240.1.









10/06/2017

Arduino - Barrière LEGO

Objets connectés, iot, Arduino, par où commencer ?

- niveau débutant, matériel requis aucun (carte Arduino ou Simulateur).
Si vous n'avez pas de carte Arduino, vous pouvez vous entraîner sur la simulation proposée par le site https://circuits.io/  . Pour chaque étape de ce tutoriel, on décrit d'abord la procédure avec la carte, puis avec le simulateur.

par exemple, à cette adresse, vous trouverez une version de la barrière LEGO ( cliquez sur "Start Simulation", puis sur l'un des deux boutons de la télécommande : triangle vers le haut, ou vers le bas pour activer le moteur dans un sens ou dans l'autre).

"La barrière LEGO, un bon projet pour débuter avec Arduino".


" ça serait bien, une barrière pour ma maison LEGO !
- Une barrière pour ta maison de LEGO, ok, qu'est-ce qu'il nous faut ? Un moteur pour actionner la barrière, et un moyen de la déclencher. Pour le moteur, on va utiliser un SG90, fourni avec la plupart des kits Arduino, et pour activer ce moteur ?? J'ai une Funduino Mega2560 qui traîne, on va voir ce qu'on peut faire avec, mais note que n'importe quelle carte Arduino, ou compatible doit faire l'affaire..."


Pour découvrir l'écosystème Arduino, nous allons donc voir aujourd'hui comment réaliser, étape par étape, une barrière LEGO.

On passe l'installation du logiciel, la connexion de la carte, et sa configuration (choix de la carte et de son port), ces sujets ont étés maintes fois traités comme ici, par exemple, le but étant ici de voir les étapes pour appréhender sa carte Arduino.

Admettons donc que vous l'ayez branchée sur le port USB, et que vous l'avez configurée (type de carte et port).

La première étape quand on veut utiliser une carte de ce type et de tester l'interaction avec, on va donc dans un premier temps tenter de lui envoyer des informations avec notre clavier.

Communiquer avec sa carte Arduino par le clavier.

Recevoir des informations envoyées par la carte.

https://circuits.io/circuits/5205037-recevoir-des-informations-envoyees-par-la-carte

La carte Arduino utilise une liaison série ( le cable USB par lequel vous l'avez branchée à votre PC). Pour voir ce qu'y se passe exactement, le logiciel Arduino est doté d'un "Moniteur Série" que l'on peut ouvrir dans le menu "Outils / Moniteur Série" ... Jusque là rien de bien compliqué.

Pour ouvrir la communication entre la carte et ce moniteur série, une instruction qui parle d'elle même  : 

Serial.begin(9600);

Serial = série, begin = démarre, 9600 = la vitesse à laquelle on souhaite communiquer avec la carte.
ceci va donc nous démarrer la communication... et pour écrire ? 

 Serial.print("Mon texte");

Vous l'aurez deviné : print = imprimer.

Bien nous avons maintenant le minimum pour attaquer notre premier programme... Ou presque... juste une petite chose avant d'y aller... dans l'éditeur Arduino, vous avez deux fonctions :

void setup(){

}
et

void loop(){

}

Ces deux fonctions sont essentielles pour le logiciel Arduino : setup représente l'initialisation du programme et loop est une boucle qui se répète à l'infini, enfin tant qu'on ne lui a pas demandé de s'arrêter ;-).

Donc pour notre premier programme, on va copier les deux instructions que l'on a vues concernant le moniteur série, à l'intérieur de la fonction setup(){ } 


void setup() {
 Serial.begin(9600);
 Serial.print("Mon texte");
}
 
void loop() {
 
}
    

Sauvegardez ce programme et "Téléversez-le" (c'est à dire envoyez-le vers la carte), ça peut se faire avec la flèche vers la droite dans le logiciel, ou par raccourcis clavier : Ctrl+r. 
D'autres raccourcis claviers qui vous seront utiles : Ctrl+s : sauvegarder et Ctrl+t : réorganiser votre code... ça peut toujours être utile.

Lorsque le logiciel /éditeur Arduino vous indique "Téléversement terminé", vous pouvez ouvrir le moniteur série (dans le menu outils ou par Ctrl+Maj+m ).
Vous devriez voir le moniteur s'ouvrir, et la ligne de texte " Mon texte" s'afficher.
Si ce n'est pas le cas, vérifier, que la vitesse de communication est bien de "9600 bauds" (en bas à droite du moniteur série.


Si vous n'avez pas de carte Arduino disponible, voici comment faire la même chose dans le simulateur CIRCUITS.IO : 

Une fois que vous êtes connecté sur le site https://circuits.io, cliquez sur "New", puis "New Electronics Lab" ("Nouveau" et "Nouveau Laboratoire Electronique").
Vous vous retrouvez alors avec la représentation d'un plaque d'essai, mais vide, on va y ajouter quelques composants, en commençant par une carte Arduino :
Cliquez sur le bouton "Components", agrandissez le bandeau qui s'est ouvert en bas ( en glissant sa limite supérieure vers le haut ), et parcourez les composants jusqu'à trouver le saint Graal, la carte "Arduino Uno R3", vous pouvez aussi facilement la trouver en tapant "uno" dans le moteur de recherche sur la droite.
Une fois que vous l'avez trouvée, glissez-la sur votre plaque d'essais et refermez le panneau des composants en cliquant à nouveau sur "Components".

Passez ensuite dans l'éditeur de code en cliquant sur le bouton "Code Editor" et de la même manière que précédemment, agrandissez ce panneau.

Un code est déjà présent, cette fois, c'est le code "Blink", qui veut dire "clignoter". Avant de l'effacer et de le remplacer par notre code de communication via le moniteur série (accessible ici par le bouton "Serial Monitor" en bas à droite), vous pouvez exécuter ce code en cliquant sur le bouton "Upload & Run" du panneau "Code Editor" ou le bouton "Start Simulation" à côté du bouton "Components" déjà vu précédemment.
L'exécution de ce code devrait faire clignoter la représentation d'une LED orange, à côté de la lettre "L", au dessus de "TX" et "RX", en plein milieu de la carte.

Si vous avez lancé le programme "Blink", stoppez la simulation par "Stop Simulation", évidemment.
Vous pouvez ensuite remplacer le code "Blink" par le code :

void setup() {
 Serial.begin(9600);
 Serial.print("Mon texte");
}
 
void loop() {
 
}


Exécutez-le ensuite par "Upload & Run" ou "Start Simulation".
Vérifiez que la carte affiche bien "Mon texte", en cliquant sur le bouton "Serial Monitor" si vous ne l'avez pas encore fait.

Bien, maintenant on en est au même point. Que ce soit la carte réelle ou la carte virtuelle, elle peut nous envoyer des informations avec l'instruction : Serial.print("Mon texte").

Vous pouvez continuez les tests en changeant le texte.
Si vous déplacez l'instruction Serial.print("Mon texte"), dans la fonction loop, et relancez la simulation, vous verrez votre ligne s'afficher à l'infini.

Envoyer des informations à la carte


Ok, maintenant que la carte peut nous parler, essayons de lui parler en retour.

Pour ce faire, on va également utiliser le moniteur série, mais dans l'autre sens.
A notre disposition, nous avons dans ce moniteur une zone de saisie, c'est là qu'il faudra taper notre texte à envoyer, et le bouton "Envoyer" (ou "Send" dans le simulateur).
Pour l'instant, si vous tapez du texte et cliquez sur le bouton "Envoyer", rien ne se passe, mais on va modifier notre programme pour qu'il "écoute" ce qu'on aura à lui dire...


A vos claviers... Prêts ? C'est parti !

D'abord, on va créer une variable au dessus de la fonction setup(){} pour pouvoir stocker le texte qui sera saisi au clavier... Appelons la, au hasard "saisie" mais vous pouvez lui donner le nom que vous voulez (à part quelques noms réservés).
On déclare donc une nouvelle variable de type "String" (chaîne de caractères) et de valeur vide  (="") :

String saisie = "";

nb : vous l'aurez certainement remarqué : les lignes ou blocs de commande se terminent par un point-virgule.

Ensuite pour que notre carte écoute ce que l'on a à lui dire, on va utiliser une méthode encore une fois liée à Serial.
d'abord :
Serial.available() pour available = diponible : on lui demande donc d'écouter/regarder si quelque chose est disponible dans Serial, c'est à dire dans le moniteur série, et si c'est le cas, on lui demandera de lire cette information et de la stocker dans la variable que nous avons précédemment créée. On pourra ensuite la manipuler, et en faire ce que l'on veut.


Comment ça se passe concrètement :
"Voir si quelque chose est disponible dans Serial" est traduit concrètement par Serail.available() > 0, c'est à dire que la longueur des choses disponibles dans Serial est plus longue que 0.
Pour tester, on utilise "if" sous la forme :

if (quelque chose){action} traduit par si 'quelque chose', alors 'action'.

On a parlé de la condition, mais qu'en est-il de l'action ?
Pour l'action, on va encore utiliser une méthode de Serial, la méthode Serial.readString(), qui veut dire "lire la chaîne de caractères".
Et une fois qu'on l'aura lue, on la stockera dans la variable "saisie" que l'on a déclarée par :
String saisie = "";

Ok, donc ? ça donne :

String saisie = "";                             // on déclare la variable 'saisie'

void setup() {                                   //on retrouve notre fonction 'setup' pour l'initialisation
  Serial.begin(9600);                        // on démarre la communication entre la carte et le moniteur série
  Serial.println("Mon texte");              /*  on teste l'affichage d'un premier texte, cela nous garantir que                                                                  la carte est bien opérationnelle */
}                                                      // fin de la fonction d'initialisation

void loop() {                                   // la fonction qui boucle est lancée
  if (Serial.available() > 0) {           // la carte teste pour savoir si quelque chose est disponible
    saisie = Serial.readString();        // si c'est le cas, elle lit l'information et la stocke dans la variable 'saisie'
    Serial.print("J'ai reçu : ");          // Elle affiche  "j'ai reçu :
    Serial.println(saisie);                 // et le contenu de ce qu'elle a reçu
  }
}

Nous avons ici de nouvelle choses :
les lignes de commentaires commencent par //
les commentaires sur plusieurs lignes sont délimités par /* et */
Serial.println() ajoute un retour à la ligne après le Serial.print();


Copiez ce code dans l'éditeur ou le simulateur, et "téléversez" ou lancez la simulation.
Rendez-vous ensuite dans le moniteur série, tapez du texte dans la zone appropriée et validez par "Envoyer" ou "Send".

La carte devrait vous répondre "J'ai reçu" suivi de votre texte.
Remarques pour le simulateur, le délai peut paraître long et le "ç" ne passe pas bien, mais vous devriez avoir une réponse !

Et voilà pour la première étape : comment communiquer avec la carte, dans un sens et dans l'autre.

Prochaine étape ?
Brancher le moteur de la barrière et le commander avec le clavier.

05/02/2017

Arduino contrôler un servomoteur avec un capteur de distance

Matériel :
- une carte Arduino
- un servomoteur (noir sur grd, rouge sur 5V, jaune sur pin 9)
- un capteur Ultrason HC-SR04 (noir sur grd, rouge sur 5V, trig sur pin 12, echo sur pin 11)

/* Utilisation du capteur Ultrason HC-SR04 pour contrôler un servomoteur*/
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

// définition des broches utilisées 
int servo = 9;
int trig = 12; 
int echo = 11; 
long lecture_echo; 
long cm;
int val;
long lastCm = 0;

void setup() 
  myservo.attach(servo); 
  pinMode(trig, OUTPUT); 
  digitalWrite(trig, LOW); 
  pinMode(echo, INPUT); 
  Serial.begin(9600); 
}

void loop() 
  digitalWrite(trig, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trig, LOW); 
  lecture_echo = pulseIn(echo, HIGH); 
  cm = lecture_echo / 58; 
   int diff = int(abs(lastCm - cm)); // detection de grand saut
 if(diff < 30){ // seulement si diff est faible
  val = min(cm,179);
  if( val< 179){

   Serial.print(diff);
   Serial.print(" : ");
   Serial.println(val);
   myservo.write(val); 
 }
 }

  delay(10); 
      lastCm = cm; 
}



25/09/2016

Google Polymer Openfisca Etalab

Un petit tutoriel pour apprendre à utiliser Openfisca de la DGFIP et d'Etalab, à partir de Polymer de Google.

OpenFisca propose une Web Api permettant de calculer prestations sociales, niveau de vie, impôts...
Polymer quand à lui permet de créer de jolies interfaces mobiles ou web à partir de webcomponents.


Prérequis

Nodejs et npm (installé avec nodejs)

Installation de Polymer-cli

npm install -g polymer-cli

Création d'un dossier de travail 

mkdir my-app cd my-app

Création de l'application

polymer init

- choisissez la ligne starter-kit
- l'application polymer doit maintenant être installé, pour vérifier, vous pouvez la lancer en utilisant la commande "polyserve" et elle devrait être accessible à l'adresse http://localhost:8080

Deux dossier nous intéressent maintenant :
- "src", c'est le dossier principal de l'application
- "bower_components", c'est le dossier des éléments de Polymer (webcomponents)

Création de l'élément "openfisca-calcul"

on va se placer dans le dossier "bower_components", créer le dossier de l'élément et créer l'élément encore une fois avec "polymer init".

cd bower_components
mkdir openfisca-calcul
polymer init

et cette fois, on va choisir de créer un élément (a blank template element)

Insertion de l'élément "openfisca-calcul"

Maintenant que notre élément est créé, on peut l'insérer dans notre application.
Allez dans le dossier "src" et ouvrez le fichier "my-view1.html" avec votre éditeur préféré.

Deux étapes sont nécessaire pour insérer un élément : l'import et le positionnement.

L'import :
<link rel="import" href="../bower_components/openfisca-calcul/openfisca-calcul.html">

Le positionnement :
Ajoutez simplement une balise ouvrante fermante représentant l'élément :

<openfisca-calcul></openfisca-calcul>

Profitons en aussi pour supprimer le "<div class="card"> ... </div>" ... on le déplacera dans notre élément

Votre fichier my-view1.html devrait maintenant ressembler à ceci :


 <!--  
 @license  
 Copyright (c) 2016 The Polymer Project Authors. All rights reserved.  
 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt  
 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt  
 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt  
 Code distributed by Google as part of the polymer project is also  
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt  
 -->  
 <link rel="import" href="../bower_components/polymer/polymer.html">  
 <link rel="import" href="shared-styles.html">  
 <link rel="import" href="../bower_components/openfisca-calcul/openfisca-calcul.html">  
 <dom-module id="my-view1">  
  <template>  
   <style include="shared-styles">  
    :host {  
     display: block;  
     padding: 10px;  
    }  
   </style>  
      <openfisca-calcul></openfisca-calcul>  
  </template>  
  <script>  
   Polymer({  
    is: 'my-view1'  
   });  
  </script>  
 </dom-module>  


Construction de l'élément "openfisca-calcul"

Avec Polymer, on favorise la réutilisation d'éléments déjà existants.
On va ici avoir besoin de trois éléments différents : 
- un "paper-button" : un bouton pour lancer le calcul,
- un "iron-ajax" qui se chargera d'effectuer la requête vers l'adresse web de l'API d'Openfisca (https://api.openfisca.fr/api/1/calculate)
- un petit "paper-spinner" pour nous indiquer que l'application est en train de traiter la requete.

L'installation de ces trois éléments se fait tout simplement : commencer par vous positionner à la racine de votre application, là où se trouve le fichier "bower.json"

bower install --save paper-button iron-ajax paper-spinner

Maintenant que ces trois éléments sont disponibles pour notre application, il ne nous reste plus qu'à les intégrer... et leur tour est joué... enfin faudra aussi taper un peu de code, on est là pour ça, quand-même...

Pour l'intégration, on opère comme avec le fichier my-view1.html.
Editez le fichier "openfisca-calcul.html" situé dans "my-app/bower_components/openfisca-calcul", et ajoutez au début les lignes suivantes :

<link rel="import" href="../iron-ajax/iron-ajax.html"> <link rel="import" href="../paper-button/paper-button.html"> <link rel="import" href="../paper-spinner/paper-spinner.html">

Ajoutez par la même occasion la ligne suivante qui nous permettra de gérer les styles : 
<link rel="import" href="../../src/shared-styles.html">


Tant qu'on est sur les styles, intégrons les en modifiant la balise <style>...< /style>  ( dans le fichier "my-app/bower_components/openfisca-calcul/openfisca-calcul.html") et en la remplaçant par :

           <style include="shared-styles">  
                :host {  
                display: block;  
                padding: 10px;  
                }  
           </style>  

Après la balise <style> ainsi modifiée, insérée l'élément concernant la requête ajax en utilisant le code suivant :

           <iron-ajax  
           id="ajaxcalculate"  
           url="https://api.openfisca.fr/api/1/calculate"  
           body="{{data2send}}"  
           method="POST"  
           handle-as="json"  
           content-type="application/json"  
           on-response="handleResponse">  
           </iron-ajax>   

Quelques explications s'imposent :

  • <iron-ajax>...</iron-ajax> : nous permet d'insérer l'élément iron-ajax qui s'occupe d'effctuer la requête.
  • id="ajaxcalculate" : un id qui nous permettra d'identifier la requete lors de l'appui sur le bouton "Calcul"
  •  url="https://api.openfisca.fr/api/1/calculate" : l'adresse url vers laquelle la requête va être envoyée
  • body="{{data2send}}" : représente les données qui vont être envoyées à l'adresse url
  • method="POST" : l'API openfisca n'accepte que le requêtes de type "POST"
  • handle-as="json" : le format dans lequel on souhaite récupérer les données
  • content-type="application/json" : le format dans lequel les données sont envoyées à l'API
  • on-response="handleResponse" : la fonction "callback" exécutée lors les résultats arrivent de l'API
Et bien voilà... on a fait le principal, ne reste plus qu'à formater les données à envoyer et traiter les données reçues...

Tant qu'on y est, profitez-en pour insérer deux <div> : un pour le bouton "calcul" et un pour le résultat :

           <div class="card">  
                <div class="circle">0</div>                 
                <paper-button raised on-tap="calcul" value="CALCUL">CALCUL <paper-spinner id="spinner" alt="Calcul en cours"></paper-spinner></paper-button>  
           </div>  
           <div class="card">  
                <div class="circle">10</div>  
                <h1>Résultat</h1>  
                <p>Revenu disponible 2015 : {{revenuDisponible}} </p>  
           </div>  


Données à envoyer et résultat

Pour les données à insérer, il faut avouer que c'est un peu compliqué de communiquer avec l'API Openfisca, mais on y arrive :
Un objet JSON (JSONObject) avec un tableau (JSONArray) nommé "scenarios" et les "variables" que l'on souhaite obtenir en sortie.
Dans le scenario, on trouve un objet "testcase" et un/des "périodes".
Dans le testcase, on défini : "familles", "foyers_fiscaux", "menages" et "individus"...
Pour simplifier ici, on va prendre l'exemple fourni par la documentation d'Openfisca.
On défini les données que l'on va envoyer : "data2send" et les données que l'on aura en résultat : "revenuDisponible"

                     data2send : {  
                          type : Object,  
                          value : {  
                               "scenarios": [  
                               {  
                                    "test_case": {  
                                         "familles": [  
                                         {  
                                              "parents": ["individu0"]  
                                         }  
                                         ],  
                                         "foyers_fiscaux": [  
                                         {  
                                              "declarants": ["individu0"]  
                                         }  
                                         ],  
                                         "individus": [  
                                         {  
                                              "date_naissance": "1980-01-01",  
                                              "id": "individu0"  
                                         }  
                                         ],  
                                         "menages": [  
                                         {  
                                              "personne_de_reference": "individu0"  
                                         }  
                                         ]  
                                    },  
                                    "period": "2015"  
                               }  
                               ],  
                               "variables": ["revdisp","nivvie_net"]  
                          }  
                     },  
                     revenuDisponible : {  
                          type : String,  
                          value : ""  
                     }       


C'est presque terminé : il reste la fonction callback lorsque l'application reçoit le résultat et le bouton pour lancer la requête :

                /**  
                     * recupere et parse la reponse du serveur  
                     */  
                     handleResponse: function(data,error){  
                          var result=data.detail.response.value;  
                          console.log("RESULTATS");  
                          console.log(result);                 
                          this.$.spinner.active=false;  
                          for (var key in result) {  
                               if (result.hasOwnProperty(key)) {  
                                    var valeur=result[key];  
                                    console.log(key+" :");  
                                    console.log(valeur);  
                               }  
                          }                 
                          // entrer ensuite dans result pour avoir les details :   
                          //     console.log(result[0].menages[0].revdisp[2015]);  
                          for (var i in result){  
                               var resultat = result[i];  
                               console.log("Revenu disponible 2015 : "+resultat.menages[0].revdisp[2015]);  
                               console.log("Niveau de vie net 2015 : "+resultat.menages[0].nivvie_net[2015]);  
                               this.revenuDisponible=resultat.menages[0].revdisp[2015];  
                          }  
                     },  


                          calcul : function(){  
                               console.log(this.data2send);  
                               this.$.spinner.active=true;  
                               this.$.ajaxcalculate.generateRequest();       
                          }  


Et voilà... le tour est joué... y'a plus qu'à cliquer sur le bouton "CALCUL"....
Allez ... si j'étais pas très clair, je vous donne le code du fichier "openfisca-calcul"... A vous d'en faire bon usage... comme par exemple un comparateur de prestations en fonction de votre situation ...



 <link rel="import" href="../polymer/polymer.html">  
 <link rel="import" href="../../src/shared-styles.html">  
 <link rel="import" href="../iron-ajax/iron-ajax.html">  
 <link rel="import" href="../paper-button/paper-button.html">  
 <link rel="import" href="../paper-spinner/paper-spinner.html">  
 <!--  
      `openfisca-calcul`  
      @demo demo/index.html   
 -->  
 <dom-module id="openfisca-calcul">  
      <template>  
           <style include="shared-styles">  
                :host {  
                display: block;  
                padding: 10px;  
                }  
           </style>  
           <iron-ajax  
           id="ajaxcalculate"  
           url="https://api.openfisca.fr/api/1/calculate"  
           body="{{data2send}}"  
           method="POST"  
           handle-as="json"  
           content-type="application/json"  
           on-response="handleResponse">  
           </iron-ajax>   
           <div class="card">  
                <div class="circle">0</div>                 
                <paper-button raised on-tap="calcul" value="CALCUL">CALCUL <paper-spinner id="spinner" alt="Calcul en cours"></paper-spinner></paper-button>  
           </div>  
           <div class="card">  
                <div class="circle">10</div>  
                <h1>Résultat</h1>  
                <p>Revenu disponible 2015 : {{revenuDisponible}} </p>  
           </div>  
      </template>  
      <script>  
           Polymer({  
                is: 'openfisca-calcul',  
                properties: {  
                     data2send : {  
                          type : Object,  
                          value : {  
                               "scenarios": [  
                               {  
                                    "test_case": {  
                                         "familles": [  
                                         {  
                                              "parents": ["individu0"]  
                                         }  
                                         ],  
                                         "foyers_fiscaux": [  
                                         {  
                                              "declarants": ["individu0"]  
                                         }  
                                         ],  
                                         "individus": [  
                                         {  
                                              "date_naissance": "1980-01-01",  
                                              "id": "individu0"  
                                         }  
                                         ],  
                                         "menages": [  
                                         {  
                                              "personne_de_reference": "individu0"  
                                         }  
                                         ]  
                                    },  
                                    "period": "2015"  
                               }  
                               ],  
                               "variables": ["revdisp","nivvie_net"]  
                          }  
                     },  
                     revenuDisponible : {  
                          type : String,  
                          value : ""  
                     }       
                },  
                /**  
                     * recupere et parse la reponse du serveur  
                     */  
                     handleResponse: function(data,error){  
                          var result=data.detail.response.value;  
                          console.log("RESULTATS");  
                          console.log(result);                 
                          this.$.spinner.active=false;  
                          for (var key in result) {  
                               if (result.hasOwnProperty(key)) {  
                                    var valeur=result[key];  
                                    console.log(key+" :");  
                                    console.log(valeur);  
                               }  
                          }                 
                          // entrer ensuite dans result pour avoir les details :   
                          //     console.log(result[0].menages[0].revdisp[2015]);  
                          for (var i in result){  
                               var resultat = result[i];  
                               console.log("Revenu disponible 2015 : "+resultat.menages[0].revdisp[2015]);  
                               console.log("Niveau de vie net 2015 : "+resultat.menages[0].nivvie_net[2015]);  
                               this.revenuDisponible=resultat.menages[0].revdisp[2015];  
                          }  
                     },  
                     /**  
                          *  
                          */  
                          calcul : function(){  
                               console.log(this.data2send);  
                               this.$.spinner.active=true;  
                               this.$.ajaxcalculate.generateRequest();       
                          }  
                     });  
                </script>  
           </dom-module>  


Le code source est téléchargeable ici https://github.com/scenaristeur

Des questions ? des erreurs ? utilisez les commentaires ci-dessous ou le forum de l'article

07/09/2016

Sparql update un Polymer element pour mettre a jour un sparql endpoint

Objectif de cet article : Créer un element Polymer pour mettre à jour un sparql endpoint (fuseki)

inspiration : https://www.youtube.com/watch?v=k1eR_3KqJms

premier test : sparql-statements (recupérer les infos RDF sur un serveur sparl / fuseki en utilisant iron-ajax)

serveur fuseki  : http://rdf-smag0.rhcloud.com/

prérequis :
installation de nodejs, yeoman

Polymer propose polymer:seed, un element modèle servant d'exemple pour la création d'elements Polymer.

Au boulot on va créer un element "sparql-update"
sous l'invite de commande dos tapez :

yo polymer:seed sparql-update

complétez avec vos infos -6> un module modèle est créé dans votre repertoire.
Pour le lancer utilisez la commande :  polyserve

Le nouvel element généré est accessible à l'adresse :
http://localhost:8080/components/sparql-update

quelques soucis parfois d'affichage, (un certain temps pour mettre à jour ? allez voir dans le fichier README.RD généré pour avoir différents liens et testez notamment celui-ci : http://localhost:8080/components/sparql-update/test/ ) , une page de tests devrait finir par s'afficher.

Ce qui nous intéresse, Thérèse , ensuite c'est le module lui-même, on utilisera deux pages :

  • la page du module :  http://localhost:8080/components/sparql-update/
  • la page de demo accessible par le bouton "DEMO" en haut à droite
Laisser le terminal ou vous avez lancez polyserve ouvert et ouvrez un autre terminal pour installer l'element "iron-ajax" avec la commande  : 
bower install --save PolymerElements/iron-ajax

et incorperez cet element dans sparql-update.html avec : <link rel="import" href="../iron-ajax/iron-ajax.html"> juste après <link rel="import" href="../polymer/polymer.html">

supprimer les elements inutiles dans le modeles : 
  • dans le fichier  sparql-update.html 
.author dans template/style
et ne garder que "properties" dans la definition js de l'element : 
il ne devrait vous rester plus que ceci : 


<link rel="import" href="../polymer/polymer.html">

<link rel="import" href="../iron-ajax/iron-ajax.html">

<!--
An element providing a solution to update sparql endpoint like Fuseki.
(https://github.com/scenaristeur/sparql-update)

Example:

    <sparql-update></sparql-update>

Example:

    <sparql-update>
      <h2>Hello sparql-update</h2>
    </sparql-update>

@demo demo/index.html
@hero hero.svg
-->

<dom-module id="sparql-update">
  <template>
    <style>
      :host {
        display: block;
        box-sizing: border-box;
      }
    </style>


  </template>

  <script>
    Polymer({
      is: 'sparql-update',

      properties: {
       
      }
    });
  </script>
</dom-module>


Nous avons maintenant un élement propre et on va pouvoir y mettre notre propre (ou sale ?) code

On incorpore maintenant notre element "iron-ajax" qui va se charger d'effectuer la requete POST vers notre serveur Fuseki :

<iron-ajax/iron-ajaxauto
url=""
handle-as="json"
on-response="{{handleResponse}}"></iron-ajax>



le mieux c'est de jeter un oeil au code