Affichage des articles dont le libellé est Apache. Afficher tous les articles
Affichage des articles dont le libellé est Apache. Afficher tous les articles

03/04/2016

Convertir sqlite, xls ou ods en RDF

L'un des buts du graph http://rdf-smag0.rhcloud.com/smag.html est d'interconnecter les bases de données disparates.

Une amie m'indique qu'elle est en train de monter une base de données sur les robots... intéressant, c'est exactement ce qu'il me faut pour mon projet Smag0, et la gestion des ressources, des objets connectes...
Voyons comment l’intégrer au graph RDF :
1 : qui va mettre à jour cette base ? Cette amie ? les constructeurs ? les utilisateurs ???
-> intégrer les données au serveur Fuseki, ou un lien vers la source de données mise à jour ailleurs ?
2 : la source actuelle est un fichier robot.db
 --> comment la transformer au format RDF ? on a deux tables robots et devices
--> j'avais dejà fait des tests pour transformer XLS et ODS en RDF , donc la première idée est d'extraire les deux tables en csv, de les convertir en ods, puis d'adapter l'outil que j'avais déjà utiliser pour repasser au format rdf... --> pas simple
--> autre option a étudier : sql.js https://github.com/kripken/sql.js 


outil d'extraction ODS vers RDF basé sur Processing 2 ( pas testé avec 3) avec :
[Une librairie permettant de gérer les fichiers ODS : https://incubator.apache.org/odftoolkit/downloads.html]
La librairie Jena Apache

15/03/2016

Rdf Facile - Afficher les informations récupérées sur AppInventor

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]

Bien dans les articles précédents, nous avons : 
- mis en place un serveur RDF / Fuseki, qui nous fournit un accès à un endpoint pour effectuer des requêtes Sparql.
- développé une application sous AppInventor pour effectuer une requête sur cet endpoint.
- modifié cette application pour ajouter des informations sur ce serveur

Nous allons maintenant reprendre cette application pour formater différemment les informations qui nous sont retournées,

On va repartir de la dernière version, celle qui permet d'ajouter des informations. On peut la récupérer ici : http://ai2.appinventor.mit.edu/?galleryId=5233374557372416

Dans la version précédente, on avait juste affiché le résultat de la requete dans la zone de texte (entre les deux version, j'avais même inséré une page pour mieux les visualiser), mais ce n'est pas ce que nous voulons, c'est illisible... on va donc reformater le résultat de la requete.

Le résultat qui nous est retourné est au format JSON et ressemble à ça :

{
  "head": {
    "vars": [ "s" , "p" , "o" ]
  } ,
  "results": {
    "bindings": [
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#range" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo1" } ,
        "p": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat2" }
      } ,
     ...
      {
        "s": { "type": "uri" , "value": "http://example.org/LucileP" } ,
        "p": { "type": "uri" , "value": "http://example.org/participe" } ,
        "o": { "type": "uri" , "value": "http://example.org/AperoboLyon" }
      }
    ]
  }
}


L'objectif étant de récupérer tous les triplets, comme celui-la : 
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } 

c'est à dire qu'on va prendre tout ce qui se trouve après '"bindings": [' et jusqu'à ']'


Pour mieux visualiser, on va modifier la requête et limiter le nombre de résultat à 3, notre variable "requeteTest" sera donc :
http://rdf-smag0.rhcloud.com/ds/query?query=SELECT+*+WHERE+%7B%3Fs+%3Fp+%3Fo+%7D%0D%0ALIMIT+3&output=json

et on va exporter le travail de formatage dans une fonction que l'on va appeler "formateTexte":
--> créer la fonction "formateTexte", la variable "resultat", et modifiez la fonction "When Web1.GotText" comme ceci :



-> Web1.GotText envoie "responseContent" à "formateTexte" dans la variable "texteAFormater"
-> Pour comprendre la fonction "formateTexte", commencez par la droite :
-> On récupère "texteAFormater", on le split/coupe à "bindings": [, on récupère le 2 ème élément de la liste créée par le split, on resplit à ] , on récupère le premier élément, et on envoie ça dans résultat, on affiche résultat dans TextBox1.

Si vous avez bien modifié la requête pour limiter le nombre de résultat à 3, le texte qui devrait maintenant s'afficher dans TextBox1 est celui-ci (revenez sur la page d'accueil et rouvrez l'écran "Visualisation" pour rafraichir, puisque la requete s'execute à l'initialisation de l'écran ou vous pouvez ajouter un bouton qui reprend le code de "When Visualisation.Initialise" pour actualiser plus vite) :  (Avec le formatage en moins )

 {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      }

Bien bien bien,
D'abord, on "trim" pour enlever les espaces au début et à la fin, et on va continuer à spliter...
L'élement qui séparent nos triplet, maintenant c'est  '} , {'
mais avec un retour à la ligne (ça fait deux heures que je suis dessus !!! mais ça passe ! )
en fait, le séparateur c'est "je ferme l'acolade, je mets un espace, une virgule, le retour à la ligne formalisé par "\n", ensuite, on a six espaces, en une accolade qui ouvre, ça donne : } ,\n {


Pour voir vraiment ce que ça donne, et où on en est, on va remplacer notre TextBox1 et  afficher nos resultats dans un gestionnaire de liste... là, vous pouvez utilisez celui que vous voulez  :
ListPicker, Spinner, ListView... ça dépend de votre besoin, ou de ce que vous souhaitez faire ensuite...
Pour la démo, j'ai mis les trois, et voilà ce que ça nous donne dans le "Designer" et le code modifié depuis la dernière image (avec le bouton actualise ) :


Et la partie code : 



Le resultat est récupérable ici : http://ai2.appinventor.mit.edu/?galleryId=4834449967022080


Evidemment, on va encore splitter pour avoir l'affichage voulu... et surtout choisir entre ListPicker, Spinner et Listview...
Bon en fait, j'hésite entre ListPicker & Listview, on verra plus tard, ... Hop ! out Spinner...

De plus, on va se refaire une petite fonction pour formater les différents élements de la List comme on le souhaite...
Un petit "Layout Horizontal" mettre notre bouton actualise à côté de "Retour Accueil " (optionnel, mais ça laisse plus de place pour le reste.

Commençons par sortir notre liste en l'envoyant à la fonction "formateItem", et on la renvoie tout de suite dans "listeItem" que l'on affiche dans nos "ListPicker" & "Listview" :


Attention, maintenant, on va spiltter... je ne détaille pas, on split sur le motif du début, on prend le deuxième element, on resplit sur le motif de fin, et on prend le premier élement, et ça pour avoir les trois elements de notre triplet : (Sujet, propriete, Objet )


On a maintenant chaque Item de la liste qui ressemble à un truc comme ça :
 "type": "uri" , "value": "http://example.org/dog1"
 "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
 "type": "uri" , "value": "http://example.org/animal"

un dernier Split pour récupérer seulement les valeurs  :



Après, on peut encore travailler sur les prefix, mais c'est déjà pas mal pour aujourd'hui...
Pour plus de fun, je repasse la limite des résultats à 100, et je vous mets le bouzin ici :
http://ai2.appinventor.mit.edu/?galleryId=4919353954271232

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]



07/02/2016

Insert d'informations sur un serveur Fuseki, post

1. installer fuseki pour qu'il soit accessible sur http://127.0.0.1:3030

2. creer un fichier smag.html  dans le repertoire webapp du serveur fuseki, avec le contenu qui suit et y accéder via http://127.0.0.1:3030/smag.html


<!DOCTYPE html>
<!-- https://github.com/scenaristeur/coolitude4/blob/master/Coolitude4/src/org/favedave/smag0/coolitude4/projet/Projet.java -->

<html>
    <body>
  
  
    </body>
   <script>
var debutRequete = "INSERT DATA { GRAPH <http://example/bookStore> {";
var finRequete = "} }";
var data="test";

</script>


<script>
function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);
console.log(params);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }


  
  
       document.body.appendChild(form);

    form.submit();
}



<!--post('/contact/', {name: 'Johnny Bravo'}); -->
//post('http://127.0.0.1:3030/test/update', {"update" : update});


function constructRequete(){

 var update  =  "PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ";
 update +=  "PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>";
     update += "PREFIX smag:   <http://smag0.blogspot.fr/NS#>";
     update += "PREFIX zoo:   <http://example.org/zoo#>";
     update += "PREFIX owl: <http://www.w3.org/2002/07/owl#>";
     update += "PREFIX ex: <http://example.org#>";
update+= "INSERT DATA {";
 //update += "GRAPH <http://smag0.blogspot.fr/GraphTest>{";
  //update += "smag:RobokIze    rdf:type         smag:Site .";
  //update +="smag:RobokIze   smag:objectif         'un site de vente revente piece detachees , pour robots, et objets connectes' ." ;
//     update += "ex:cat     rdfs:subClassOf  ex:animal .";
//     update += "zoo:host   rdfs:range       ex:animal .";
//     update += "ex:zoo1    zoo:host         ex:cat2 .";
//     update += "ex:cat3    owl:sameAs       ex:cat2 .";
//    update += "ex:cat3    owl:sameAs       ex:cat2 .";
  
    var sujet=document.getElementById("sujet").value;
    var propriete=document.getElementById("propriete").value;
    var objet=document.getElementById("objet").value;
 update += "smag:"+sujet+"    smag:"+propriete+"         smag:"+objet+" .";

 // fin requete avec graphe var finRequete = "} }";
 var finRequete = "}"; // fin requete sans graphe

update+=finRequete;
console.log(update);


post('http://127.0.0.1:3030/test/update', {"update" : update});
    //console.log(update);
  
    //console.log(document.getElementById("sujet").value);
    //window.location.assign('http://127.0.0.1:3030/smag.html');
//modifier la pause créée par l'alerte --> ceci permet la mise à jour par la fonction post
    alert(update);
    maj();
}

function httpGetAsync(theUrl, callback)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
           callback(xmlHttp.responseText);
            //console.log(xmlHttp.responseText);
             //document.getElementById("result").innerHTML = xhttp.responseText;
    }
    xmlHttp.open("GET", theUrl, true); // true for asynchronous
    xmlHttp.send(null);
}

function updateDiv(data){
var myJSONOBJECT= eval('(' + data+ ')');
// ou var myJSONOBJECT= JSON.parse(data, reviver);
var bindings = myJSONOBJECT.results.bindings;
//console.log("update");
//var resultat="";
var list = document.getElementById('resultats');
while (list.firstChild) {
    list.removeChild(list.firstChild);
}
for(i in bindings) {
  var binding = bindings[i];
  //alert(binding); // a for-loop to print all the bindings
  sujet=binding.s.value.split("#")[1];
  propriete=binding.p.value.split("#")[1];
  objet=binding.o.value.split("#")[1];
//  resultat=sujet +" "+propriete+" "+objet;
 // console.log("resultat :"+resultat);
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(sujet));
entry.appendChild(document.createTextNode("  -> "));
entry.appendChild(document.createTextNode(propriete));
entry.appendChild(document.createTextNode("  -> "));
entry.appendChild(document.createTextNode(objet));
list.appendChild(entry);
}
//document.getElementById("result").innerHTML = resultat;

//var bindings = sr.results.bindings;

// JavaScript  for...in loop iterates
// through the properties of bindings array
// which are [0,1,length-1] as opposed to the
// array item.

//for(i in bindings) {
 // var binding = bindings[i];
 // alert(binding); // a for-loop to print all the bindings
//}

// The only difference here (a subtle one) is
// that the iterator variable is n as opposed to r
// n=name, r=row index
//for(i in bindings) {
  //var binding = bindings[i];
  //for(n in binding) {
  //  alert(binding[n].value); // a nested for-loop to print binding values
 // }
//}



}


function maj(){
//console.log('maj');
httpGetAsync('http://127.0.0.1:3030/test/query?query=select+*+where{%0D%0A%0D%0A%3Fs+%3Fp+%3Fo}%0D%0A&output=json',updateDiv);

}

</script>



<form name="form1" onsubmit="constructRequete()">
<input type="texte" name="q" value="a">

 <input type="submit">
</form>

<ul id="resultats"></ul>

<div id="result">

</div>

<script>

setInterval(function(){ maj(); }, 3000);
//maj();

            var inputSujet = document.createElement("input");
            inputSujet.setAttribute("type", "text");
            inputSujet.setAttribute("name", "sujet");
            inputSujet.setAttribute("id", "sujet");
            inputSujet.setAttribute("placeholder", "Sujet");
          
            form1.appendChild(inputSujet);
          
            var inputPropriete = document.createElement("input");
            inputPropriete.setAttribute("type", "text");
            inputPropriete.setAttribute("name", "propriete");
            inputPropriete.setAttribute("id", "propriete");
            inputPropriete.setAttribute("placeholder", "propriete");

            form1.appendChild(inputPropriete);
          
            var inputObjet = document.createElement("input");
            inputObjet.setAttribute("type", "text");
            inputObjet.setAttribute("name", "objet");
            inputObjet.setAttribute("id", "objet");
            inputObjet.setAttribute("placeholder", "Objet");

            form1.appendChild(inputObjet);
  
    // console.log(document.getElementById("sujet").value);
</script>


</html>

01/12/2015

Reinstallation pcduino et configuration du rover



(Update 07/01/2016)
un nouveau script d'installation qui reprend la procédure décrite dans cette page est dispo ici .








Si votre pcduinoBot plante, ou si vous posséder cette merveilleuse carte qu'est le pcduino et ne savez pas trop quoi en faire, je vous propose d'y installer les fonctionnalités regroupées sous le terme de pcduinoBot.


Vous pouvez repartir de zéro en suivant la procédure indiquée ci dessous :
- pour la partie technique, jetez un coup d'oeil là http://smag0.blogspot.fr/2014/03/rover-pcduino-introduction.html
- utilisation d'une carte pcduino V2, avec module wifi noir : commander le kit matériel complet ou seulement certaines parties

REINSTALLER LE SYSTEME :


- télécharger les images Kernel et Ubuntu ici : http://www.linksprite.com/image-for-pcduino2/
- les installer selon la procédure ici : http://www.mon-club-elec.fr/mes_downloads/doc_pcduino/3.pcduino_installation_maj_du_systeme_de_base.pdf ou là : http://learn.linksprite.com/pcduino/quick-start/steps-to-flash-ubuntu-images-to-pcduino/
ou la méthode plus rapide avec PhoenixSuit plus bas sur cette page.

ACTIVER 4GB DE NAND SUR VOTRE PCDUINO

http://learn.linksprite.com/pcduino/quick-start/how-to-use-the-4g-nand-flash-for-pcduino/
le lien mentionné ne fonctionne plus , mais dans les commentaires, y'en a un autre sur un site russe, pour vous éviter d'apprendre le russe, je l'ai mis là ... pour voir la taille de vos disques utilisez la commande "df -h"
avec la notice :
We prepared a script pcduino-nand-4g-fix to help you extend the space.You can download it, unpack it, and run: $chmod +x pcduino-nand-4g-fix $ sudo ./pcduino-nand-4g-fix it will output: partition  0: name =   bootloader, partition start =     2048, partition size =    65536 partition  1: name =          env, partition start =    67584, partition size =     4096 partition  2: name =         boot, partition start =    71680, partition size =    32768 partition  3: name =       rootfs, partition start =   104448, partition size =  3686400 partition  4: name =        UDISK, partition start =  3790848, partition size =  3991552 5 partitions check partition table copy 0: OK check partition table copy 1: OK check partition table copy 2: OK check partition table copy 3: OK ready to write new partition tables: partition  0: name =   bootloader, partition start =     2048, partition size =    65536 partition  1: name =          env, partition start =    67584, partition size =     4096 partition  2: name =         boot, partition start =    71680, partition size =    32768 partition  3: name =       rootfs, partition start =   104448, partition size =  7677952 4 partitions write new partition tables? (Y/N) y Press  “Y”  to confirm, the system will reboot automatically. After reboot, you will get full 4GB.

MJPG-STREAMER :

 - http://learn.linksprite.com/pcduino/install-mjpg-streamer-pcduino/, attention, erreur dans le lien de téléchargement, complétez avec ça : http://doc.ubuntu-fr.org/mjpg-streamer
- à lancer dans un terminal avec la commande


$ mjpg_streamer -i "/usr/local/lib/input_uvc.so -d /dev/video0  -y -r 320x240 -f 10" -o "/usr/local/lib/output_http.so -p 8090 -w /usr/local/www -p 8090"

ceci lance un serveur accessible à l'adresse http://127.0.0.1:8090 et diffuse en Streaming l'image de votre caméra branchée sur le port USB. On récupérera cette image ensuite, et on l'affichera ensuite avec le serveur python qui gérera les commandes.

Pour lancer la webcam au démarrage, ainsi que le serveur python du paragraphe suivant, éditez le fichier autostart en lançant la commande suivante :

$ sudo leafpad /etc/xdg/lxsession/Lubuntu/autostart

et ajoutez les deux lignes suivantes (la deuxieme est en fait une seule ligne ):

@python /home/ubuntu/smag0/serveur/serveur.py
@mjpg_streamer -i "/usr/local/lib/input_uvc.so -d /dev/video0  -y -r 320x240 -f 10" -o "/usr/local/lib/output_http.so -p 8090 -w /usr/local/www -p 8090"

POUR AVOIR UN JOLI SERVEUR PYTHON PERMETTANT DE COMMANDER NOTRE ROBOT PCDUINO :

installation de Flask : (http://flask.pocoo.org/)

$ sudo apt-get install python-pip python-dev build-essential 
$ sudo pip install --upgrade pip 



$ sudo pip install Flask

librairie Pyduino

Installer la librairie Pyduino pour l'accès aux PWM en mode analogique et contrôler la vitesse des deux moteurs à courant continu (DC). La taille de notre pcDuino étant comme nous l'avons vue, extensible... mais pas indéfiniment, on peut choisir de n'installer que la librairie est ses prérequis :

Attention la commande d'installation manuelle est à exécuter avec les droits admin : 
$ sudo ./install_pyduino.sh 



Téléchargez et décompressez le code du serveur python pour commander le pcduino rover et voir les images en streaming : le code du serveur est dispo ici 
corriger l'adresse http://192.168.XX.XX:8090 dans la page dimmer-light.html du repertoire template et mettez celle de votre pcduino

à décompresser dans le repertoire /home/ubuntu/smag0, et à lancer avec

$ cd /home/ubuntu/smag0/serveur
$ python serveur.py
vous devriez voir le lancement du serveur, celui-ci est ensuite accessible à l'adresse http://127.0.0.1:8080, ou par le réseau (récupérez l'adresse du pcduino avec un ifconfig, à ce moment , le mieux est d'attribuer une adresse ip fixe à votre carte pcduino, dans la configuration de votre box, ma box sfr le fait très bien, et j'imagine que la votre aussi.)
Il y a même possibilité de demander à votre box de router les entrées sur votre pcduino, afin de permettre de voir les images, ou déplacer votre pcduino rover depuis le bureau... ça fonctionne très bien, mais c'est juste en test, attention, je ne garanti pas la sécurité. c'est à vous de savoir quels ports vous ouvrez, à qui, comment...)

le résultat devrait être proche de ça :


voir aussi, ce qu'on peut faire avec nodejs : https://www.npmjs.com/package/pcduino
et/ou avec p5js : http://p5js.org/gallery/
p5js +nodejs + socket.io  -->  https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io

d'autres solutions pour monter un serveur web /socket sur le pcduino : http://indexerror.net/2492/bottle-autobahnpython-pcduino

INSTALLATION FUSEKI (OPTIONNEL)


INSTALLATION JENA


modifications à réintégrer dans le code du fichier dimmer-light.html de serveur.zip (repertoire templates): 
<div style="float:left">
<img id="snapshot" src="" class="rotate270"/>
<script> var loc=window.location.hostname;
loc+=':8090/?action=stream' ;
console.log(loc);
document.getElementById("snapshot").src="http://"+loc;
</script>
</div>

PCDUINO EN MODE HOPSPOT / POINT D'ACCES / ACCESS POINT / AP

j'ai testé ça, mais ça m'a planté la carte wifi http://blog.sip2serve.com/post/48899893167/rtl8188-access-point-install-script, mais on peut peut-être s'en inspirer, et mettre les paramètres de cette page, ou voir là : --> marche pas pour l'instant. ça a marché qd j'avais reçu mon pcduino, mais depuis qques mises à jours --> pb


LA BIBLE DU PCDUINO :
http://www.pcduino.com/wiki/index.php?title=Book

images pcduino : http://www.linksprite.com/image-for-pcduino2/

pour l'erreur (error) : Unable to connect to www.wiimu.com:8020:
-->It seems that the server has been closed.

Try this temporary source in your sources.list:


Reinstaller l'image du pcduino avec PhoenixSuit

(bien que cette page concerne le pcduino 3, fonctionne aussi avec mon pcduino2. plus rapide que de graver l'image sur SD.)

-brancher le pcduino au secteur
-brancher un autre cable sur la prise otg du pcduino 2
-appuyer sur upgrade puis un coup sur Reset, et Phoenixsuit envoi la mise à jour sur la carte.
-brancher ensuite une clé usb avec un fichier update.sh et  l'image d'ubuntu / ou du pcduino rover (page 64 : https://s3.amazonaws.com/pcduino/book/Rover+-+A+WiFi+Video+Surveillance+Remote+Robot++Powered+by+pcDuino.pdf)


NOTES RAPIDES

pcduino v2

- mettre le clavier en français :
infos pour éviter des galères : 
régler l'heure sur pcduino :  sudo ntpdate fr.pool.ntp.org 
régler le clavier en français : sudo setxkbmap fr

sudo board-config.sh
- configurer la carte avec "board-config" : http://www.mon-club-elec.fr/mes_downloads/doc_pcduino/3b.pcduino_utilitaire_board_config.pdf
- install de pip à rajouter dans le script de réinstall du rover : sudo apt-get install python-pip python-dev build-essential

```
Try this
sudo vi /etc/apt/sources.list
and then make sure uncomment the `wiimu.com' lines and add 'trusty-security / trusty-updates' sources as downbelow
deb http://ports.ubuntu.com/ubuntu-ports/ trusty main universe
deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty main universe

deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main universe
deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main universe

deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main universe
deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main universe

# deb http://www.wiimu.com:8020/pcduino/ pcduino main
# deb-src http://www.wiimu.com:8020/pcduino/ pcduino main
then do 
sudo apt-get update
again, everything works well without annoying 'conflict' or 'pcduino-kernel error' blah blah
```

27/03/2014

Réclamations, Doutes, Demandes

On est partis pour... Ok, si je considère... allez... que dans 20 ans tout sera connecté dans ma maison et branché sur internet et commandable par mon smartphone (ou autre...)
Un paquet de questions se posent ...
Parce qu'un projet comme ça pose beaucoup de problème : éthique, sécurité, confidentialité, ...

Si vous avez des doutes, des peurs, des requêtes, des oppositions, quand au projet, ... c'est normal, j'ai aussi souvent peur de ce que je ne connais pas ...

On va tenter de  trouver des solutions à ces questions :
- Les robots vont-ils donner plus de chômage ?
- Vais-je perdre mon boulot ? 
- Qui est responsable d'un robot qui commettrait un délit ?
- Comment être sûr que mes informations personnelles ne sont pas diffusées sur le Net ?
- Comment désactiver un robot qui se trouverait dans ma maison ... et que j'y ferais des trucs que je n'ai pas envie qu'il voie ?
- Comment être certain que le robot dont j'ai besoin sera disponible au moment où j'en aurai besoin ? 
- Où vont-ils se ranger dans ma maison ?
- Comment le robot qui me fera le café va t-il savoir que le matin je mets deux sucres dans mon café et que le soir je n'en met qu'un ?
... et toutes les autres questions que vous pourriez-vous poser...

 Je vous invite au "Café des prudents, sceptiques & des opposants" : le café PSO, la discussion y est libre et plus elle sera virulente, plus on pourra approfondir les sujets et trouver des solutions.
Et juste à côté du café PSO, on va ouvrir le café SPO... le "Café des Sujets, Propriétés, & Objets", ce café parlera plus de technique et de la manière dont l'information peut être stockée : sous forme de triplet avec  :
un sujet, une propriété, un objet.
pour faire simple : 
<voiture> <couleur><rouge>
<david><age><37>
<pcduino Rover><type><robot>
...

d'autres cafés sont en train d'ouvrir leurs portes... Tenez... par exemple, je vois là-bas M. GéoTrouvetout... c'est lui qui tient le "café DIMB & DUMB" , le café des DIYeurs, des inventeurs, des makers et des bricoleurs, il y a également Mr Holon qui tient le "café SMA" , le café des Agents et des Multi-agents..., et d'autres encore... des boutiques, aussi où les inventeurs et fabricants exposent leurs projets... que du beau monde... il y a même un espace réservé pour l'utilisation du projet Smag0 par les enfants...

Vous trouverez également LA MAISON DES DEFIS : c'est l'endroit où l'on réalise les trucs qui ne sont normalement pas réalisables...
Et la place reste ouverte... n'importe qui peut se poser sur un banc et lancer un sujet de conversation, une idée, un problème...


Pour afficher le groupe de discussion en pleine page, suivez ce lien

24/03/2014

Créer une interface pour visualiser les ontologies avec Processing

Un petit tutoriel ?

Ca fait un bout de temps que je cherche, mais là je pense être sur une bonne piste. Le but étant de pouvoir créer facilement l'interface d'une application, en décrivant ses étapes dans une ontologie.
Après quelques tests et , l'utilisation de Processing semble être une piste encourageante  ;-).

Et même permettre à des non programmeurs de créer des applications, simplement en les décrivant !

Voici donc la recette d'un "Processing de HelloRdf à la sauce Jena", récupérant les information dans une ontologie (RDF/OWL), le but étant ensuite de récupérer les informations décrites dans la méthode diamond.owl ou de toute autre méthode écrite en rdf/owl pour créér l'application adéquate ;-).
On devrait de la même manière pouvoir visualiser des requêtes Sparql qui retournent des flux formatés RDF.

Pour ceux qui sont trop pressés, le fichier source est disponible ici ( Clic sur Fichier, puis télécharger pour récupérer l'archive complète , A ouvrir avec Processing)
-   helloRdf.zip 
- une autre version avec visualisation de toutes les classes Smag0touteclasseOK


" Processing de HelloRdf à la sauce Jena"

Ingrédients : 

- 1 petit fichier owl/rdf ,
- quelques lignes dans un sketch Processing ,
- quelques librairies Jena pour lier le tout.

Instructions : 

1 : Commençons par préparer nos outils de travail. 


Téléchargez et décompressez, si ce n'est déjà fait, les trois outils suivants. Vous trouverez sur chacun des sites de la documentation détaillée pour l'installation et l'utilisation  :
  1. Protege (version utilisée 4.3.0)
  2. Processing (version utilisée 2.1.1)
  3. Jena (version utilisée 2.11.1)
Un tutoriel de prise en main de chacun de ces logiciels est disponible tout en bas de cette page pour ceux qui ne les maîtriseraient pas  ;-).

Protege et Processing sont des applications et vous pouvez les utiliser directement, par contre, pour Jena, on va seulement utiliser les librairies, comme le décrit Ian Dickinson dans son tutoriel dédié à l'intégration de Jena dans Eclipse :
Commencez par lancer Processing et créez un nouveau sketch vide (un sketch étant un programme dans Processing)  et enregistrez le, par exemlpe sous le nom "helloRdf".




Ceci devrait vous créer un nouveau répertoire "helloRdf" dans Mesdocuments/Processing qui est le répertoire par défaut des sketches de Processing , et à l'intérieur de celui-ci, un fichier helloRdf.pde. Pour visualiser ce répertoire, vous pouvez utiliser le menu Sketch/Show Sketch Folder de l'application Processing.








Comme décrit pour l'intégration de Jena dans Eclipse (Blog de Ian Dickinson) nous allons intégrer les bibliothèques de Jena.

Commencez par créer un répertoire
"code" dans le répertoire helloRdf, juste à côté (ou au dessous ;-) du fichier helloRdf.pde. Profitez en également pour créer un répertoire "data" qui nous servira par la suite pour y stocker les fichiers de données :



Rendez-vous ensuite dans le répertoire ou vous avez décompréssé Jena et copiez toutes les librairies (.jar) se trouvant dans le répertoire lib et collez -les dans le répertoire "code" que vous avez créé précedemment dans le répertoire du sketch helloRdf.








Maintenant que nous sommes prêts, mettons-nous au travail.


2 : Création de l'architecture du sketch Processing :


Processing étant basé sur Java , on peut y intégrer toute sorte de package de la même manière, avec import.
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;

Insérez ensuite les deux fonctions primordiales de Processing qui permettent de mettre en place (setup) et de dessiner (draw) :

void setup(){

}

void draw(){
}

A l'interieur de la fonction setup(), saisissez les lignes suivantes pour déterminer la taille de l'application et sa couleur de fond : 

  size(300, 300);
  background(255,255,128);


Cliquez ensuite sur l'icone du triangle (ou CTRL+R) pour executer votre code :





Vous devriez voir apparaitre une fenetre identique à celle-ci :



Vous pouvez tester avec d'autres valeurs pour voir leur effet :
size (largeur de la fenêtre, hauteur de la fentre);
background(rouge, vert, bleu, alpha);

Bien ! maintenant que nous savons utiliser Processing, passons aux choses sérieuses : Le paramétrage de cette application grâce à un fichier la décrivant, j'ai nommé l'ontologie "hello.owl"


3. Création de l'ontologie de configuration hello.owl

Commençons par une ontologie très simple, composée d'un seul "Individual", on ne peut pas faire plus simple comme ontologie .
Lancez Protégé et cliquez sur l'onglet "Individuals" :


Cliquez ensuite sur le losange violet avec un plus (attention ! celui qui se trouve dans la fenêtre Individuals, car il y en a plusieurs) :



Créez un nouvel "Individual", c'est à dire une nouvelle Entité (ou Instanciation) et nommez la ProcessingConfiguration en respectant les majuscules :




Le nouvel Individual doit apparaitre dans la fenêtre correspondante :






Profitez-en pour sauvegarder votre fichier "hello.owl" au format (RDF/XML) dans le répertoire "data" du sketch HelloRdf que nous avons précédemment créé avec Processing, par la commande File / SaveAs :


 Enregistrement au format (RDF/XML) dans le répertoire data du sketch HelloRdf




Pour info, il arrive assez régulièrement que Protégé bloque, ou plante carrément quand on tente de cliquer sur un élément tout récemment créé. Si ça vous arrive aussi, pensez à sauvegarder régulièrement ;-).

Ondevrait ensuite pouvoir modifier l'entité ProcessingConfiguration, lors du test et de la confection des copies d'écrans, ça semble bloquer... ok je supprimme cette entité (losange avec une croix dessus) et je la recréé depuis l'onglet Entité en cliquant sur le plus situé à côté de "membres"



Création de l'Entité ProcessingConfiguration :




Cliquez maintenant sur cette Entité, puis sur DataPropertyAssertion, pour lui ajouter des propriétés sizeX, sizeY, background, (grâce aux trois boutons verts) vous devez enregistrer les valeurs une par une et valider à chaque fois :




Voici l'Individual ProcessingConfiguration avec ses propriétés ( attention dataProperty et non Object Property) :



Sauvegardez de nouveau votre fichier "hello.owl" , il est prêt à être utilisé par notre sketch HelloRdf !

4. Les fondations de notre applications étant posés, attaquons nous au bati ! Ah! Tiens ! c'est plus une recette ???

Nous aurons besoin deux deux nouvelles classes dans le sketch HelloRdf : l'une pour instancier notre application et une autre servant d'utilitaire pour la lecture du fichier..


En cliquant dans Processing sur le petit triangle vers le bas vous pourrez créer un "NewTab"... et bien créez en deux : l'un nommé "Application", et l'autre  "OwlFile" et remplissez les comme suit  ( n'oubliez pas de modifier également le premier fichier ( HelloRdf avec le setup qui instancie l'application et récupère les valeurs de cette application !)








code complet de la classe Application : 


class Application {

  String defaultInputFileName="hello.owl";
  int sizeX = 10;
  int sizeY = 20;
  color background = color(0, 0, 0);
  Model model = ModelFactory.createDefaultModel();
  String NS;
  String configURI;


  Application() {
    OwlFile owlFile = new OwlFile(defaultInputFileName);
    creation(owlFile.model);
  } 

  void creation(Model _model) {
    model = _model;
    NS = model.getNsPrefixURI("");
    println("Namespace : "+NS);
    //model.write(System.out);
    // recupere la configuration pour Processing, mais possibilite de creer d'autres fichiers de config selon les supports (html5, Java, ruby, python...) !
    readConfiguration(model, "Processing"); 

    // Affiche la configuration
    println("\n**********************************************************************************\n**********************************************************************************\n");
    println("Cette application utilise le fichier de configuration : \t" +defaultInputFileName);
    println("Les informations de configurations sont des propriétés de l'individual \t "+configURI);
    println("Config décrite dans ce fichier : background :"+hex(background)+" + size : ("+sizeX+","+sizeY+")");
    println("de la même manière, on doit pouvoir creer des pages différentes, des formulaires, des animations, des boutons, des agents (? ;-P)...");
  }


  void readConfiguration(Model _model, String _metaApplication) {
    model = _model;
    String metaApplication = _metaApplication;
    // determine la configuration en fonction de la MetaApplication (une meta application permettant de creer une autre application)
    configURI = NS+metaApplication+"Configuration";
    String sizeXURI = NS+"sizeX";
    String sizeYURI = NS+"sizeY";
    String backgroundURI = NS+"background";
    Resource config  = model.createResource(configURI);
    Property sizeXprop = model.createProperty(sizeXURI);
    Property sizeYprop = model.createProperty(sizeYURI);
    Property backgroundProp = model.createProperty(backgroundURI);
    sizeX =  int(config.getProperty(sizeXprop).getObject().toString());
    sizeY =  int(config.getProperty(sizeYprop).getObject().toString());
    background  =  unhex(config.getProperty(backgroundProp).getObject().toString());
    println("test :"+sizeX+ " "+ sizeY+" "+hex(background));
  }
}

Code complet de la classe OwlFile : 

class OwlFile {
  String inputFileName;
  BufferedReader reader;
  Model model = ModelFactory.createDefaultModel();

  OwlFile(String path) {
    ouverture (path);
  } 

  void ouverture(String _path) {
    inputFileName = _path;
   // println ("cette application utilise le fichier " +inputFileName+);
    reader = createReader(inputFileName);
    // lire le fichier RDF/XML
    model.read(reader, null);
    // l'écrire sur la sortie standard
    // model.write(System.out);
  }
}

Code complet du premier fichier helloRdf.pde :


import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;

Application application;

void setup(){
  application = new Application();
  size(application.sizeX, application.sizeY);
  background(application.background);
}

void draw() {
  
}


Sauvegardez et cliquez sur le triangle pour lancer l'application helloRdf avec les propriétés que vous avez saisies dans Protégé au format RDF.





Reste plus qu'à récupérer les classes et les Individuals de l'ontologie diamond.owl, et les lier par leur propriétés , pour ce faire, voir  : http://www.gicentre.net/utils

Pour ceux qui sont trop pressés, le fichier source est disponible ici ( Clic sur Fichier, puis télécharger pour récupérer l'archive complète , A ouvrir avec Processing)
-   helloRdf.zip 
- une autre version avec visualisation de toutes les classes Smag0touteclasseOK

Pour Zoomer, tourner, et deplacer : https://www.youtube.com/watch?v=LBrGDqxusVA

Et pour ceux qui découvrent Processing : http://fr.flossmanuals.net/_booki/processing/processing.pdf
Et pour ceux qui découvrent Protégé et les ontologies : http://python.espe-bretagne.fr/master-hst-ue9-2/wp-content/uploads/2013/03/Tutoriel-Pizza-gloria-1.pdf
Et pour ceux qui découvrent Jena :  http://igm.univ-mlv.fr/~ocure/LIGM_LIKE/Teaching/imac3/5_SW.pdf

A plus.... au plaisir de lire vos remarques et commentaires, ou contributions ;-)

Bon c'est pas le tout de rigoler.... mais faut que j'aille bosser, moi...