jeudi 10 novembre 2011

Nabaztag V2 : Clonage des services Nabizdead


Objectif : Installer très facilement son propre serveur web "myNabizdead" en 5 minutes (une fois bien rôdé) et 10 lignes de php ! Sources Zip

Requis : Un hébergement web supportant le .php et les fichiers .htaccess

Le serveur ainsi cloné sur la base de www.nabizdead.net est entièrement autonome (et totalement ouvert aux dévs...). Il peut aussi être chaîné avec d'autres serveurs ou services web afin de founir un réseau maillé plus important offrant de très nombreux services à la carte.

Le serveur myNabizdead peut aussi être vu comme un proxy qui pourrait s'intercaler entre le lapin et le serveur Nabizdead original (www.nabizdead.net) pour diffuser des informations particulières et redonner la main au serveur suivant.

On peut ainsi imaginer de nombreuses utilisations : personnelle, communautaire, domotique, bureautique voire même industrielle. Il n'y a donc plus de limite pour ce type de serveur, à part votre imagination.

Les commandes interactives envoyées au Tag:tag sont en langage clair (ex: SAY ASK MP3 COLOR SLEEP WAKEUP...) et permettent très facilement le développement de nombreuses applications de type Quizz, Histoires interactives, Flux d'informations, Nabcasts, etc...
 On notera qu'il n'est pas nécessaire de "monter" son serveur myNID pour fournir du contenu aux Nabaztags de la communauté : une simple page web suffit, dès l'instant qu'elle renvoie les commandes dans le format attendu par le lapin en mode texte. On ne peut plus simple. (cf Langage NID)

Sources Zip

On procède en 2 étapes principales :

Installation du "boot_code" chargé par le Nabaztag:tag lors de sa mise sous tension

Modification & Interception des demandes (requêtes) du Nabaztag:tag

1. Installation & paramétrage du Boot

Lorsque le lapin est allumé et connecté au wifi, sa première demande est de récupérer un fichier "boot" par un appel à http://adresse_mon-serveur/bc.jsp (adresse_mon-serveur est/sera défini dans le setup du lapin. Ex: mynid.free.fr).

Installer les 5 fichiers contenus dans Sources Zip sur son serveur web dans le répertoire qui va bien; càd celui qui sera défini dans le setup du lapin : ici adresse_mon-serveur (ex: à la racine de mynid.free.fr).

Le fichier .htaccess associé au répertoire web permet de transformer l'appel initial /bc.jsp en /_bc.php.

Le script _bc.php gère l'envoi du fichier de boot (ici bc.nid-wizz.bin) vers le Nabaztag:tag lors de son démarrage.

Il faut maintenant modifier le setup du Nabaztag:tag pour lui indiquer le nom de son nouveau serveur (adresse_mon-serveur).
 Le lapin doit donc démarrer en chargeant le boot que l'on vient d'installer. Il communique maintenant avec le serveur nabizdead.wizz.cc par défaut.

Note : On peut aussi indiquer dans le setup une adresse de serveur du genre adresse_mon-serveur/dirxxx. En effet si on désire installer plusieurs serveurs myNabizdead sur un même serveur physique, il faut alors les différencier par le nom du répertoire, car le premier appel à la mise sous tension se fait toujours sur le nom du script bc.jsp codé dans le firmware (ici l'appel serait http://adresse_mon-serveur/dirxxx/bc.jsp). Dans ce cas, il faudra bien sûr installer les fichiers dans chaque répertoire dirxxx de son serveur web.

2. Intercepter les requêtes du Nabaztag:tag

A la fin de l'étape 1 précédente, le Nabaztag:tag communique par défaut avec le serveur nabizdead.wizz.cc en lui envoyant des requêtes ("ping"), à intervalles réguliers, sur l'adresse (pour l'instant) http://nabizdead.wizz.cc/p.php.

C'est la fonction principale du script p.php qui est donc le programme central vers lequel convergent toutes les demandes ("ping") du Nabaztag:tag. Le nom de ce script (p.php), ainsi que le nom du serveur, sont inscrits en dur dans le fichier de boot bc.nid-wizz.bin.

Pour communiquer avec votre serveur (et non plus nabizdead.wizz.cc par défaut), voici donc l'ultime et délicate modification à apporter au fichier de boot (bc.nid-wizz.bin) :

Comme la communauté n'a pas (encore) les sources du fichier boot, il faut donc opérer directement dans le binaire avec l'aide d'un éditeur hexadécimal (cf Hex Editor Neo).

En fait, en analysant plus précisément le protocole de communication entre le lapin et le serveur, on s'aperçoit que les requêtes sont envoyées sur une ip figée plutôt que vers un nom de domaine... je ne sais pas trop pourquoi (mais j'ai qd même une petite idée...). Ca peut devenir un tout petit peu embêtant pour certains hébergements. On s'attendait à voir une requête du genre http://www.nabizdead.net/p.php?xxx mais c'est http://213.186.33.17/~nabizdea/p.php?xxx qui apparait ! (l'ip 213.186.33.17 étant un cluster OVH). Il va donc falloir ruser pour rentrer dans le moule...
Charger le fichier boot binaire bc.nid-wizz.bin dans l'éditeur Hex Neo et se rendre directement à l'offset 0x0e5e. C'est le répertoire d'accueil de votre serveur codé sur 10 octets. Ici /~wizzbnpy (anciennement ~nabizdea). Ca tombe bien, mon serveur est aussi chez OVH ! Pour les autres, va falloir faire avec...
 Remplacer /~wizzbnpy par votre répertoire d'accueil sur 10 caractères.

Maintenant, 8 octets avant, on trouve l'ip du serveur distant : offset 0x0e56 à 0x0e59. Ici bc a5 07 13 correspondant à 188.165.7.19 soit le cluster qui héberge nabizdead.wizz.cc (anciennement b5 da 21 11 soit 213.186.33.17 le cluster qui héberge www.nabizdead.net). Rebelote , il faut modifier ces 4 octets avec l'ip de notre serveur en hexa.
Facultatif (?) : Dans le doute, modifier les 17 octets (qui contiennent nabizdead.wizz.cc) situés à l'offset 0x0f9e. Il faut donc trouver un nom de domaine/sous-domaine sur 17 caractères : par exemple mynid0001.ovh.net (l'original était www.nabizdead.net). Je ne sais pas si réellement ce domaine est utilisé quelque part. Pour moi, il aurait dû l'être en lieu et place de l'ip/rép vu plus haut...

Du coup , ne pas oublier de déplacer le fichier p.php vers le bon serveur/répertoire (ou installer une redirection dans un .htaccess à la racine du répertoire d'accueil).
Sauvegarder le fichier .bin ainsi modifié (sa taille doit rester à 22426 octets bruts) et le mettre à jour sur votre serveur web.
Re-demarrez le Nabaztag:tag (débrancher/attendre 20 secondes/rebrancher). Et normalement bingo !

Note : L'emplacement du fichier p.php peut être finalement différent de celui du _bc.php. En effet, ces 2 scripts sont totalement indépendants. On peut charger le boot_code sur un premier serveur (celui indiqué dans le setup du Nabaztag:tag) et répondre aux demandes (ping) sur un second serveur (celui indiqué dans le fichier boot bc.nid-wizz.bin).

Les commandes disponibles sont listées dans le script. Avec un peu de temps et d'exemples, on connaitra la logique de chacune de ces commandes.
ASK
ASKANY
ASKDELAY
DYN
COLOR
CUT
LANG
MP3
MSK
REBOOT
RESET
SAY
SNDTHR
SLEEP
TIME
WAKEUP
WAIT

Voir aussi le post sur le Boot Tag:Tag.

3. Facultatif : interception du TTS Google

La cerise sur le gâteau : intercepter le TTS Google pour le re-diriger vers un tts plus élaboré (type ACapela, VoxCards, etc...) ou carrément ajouter de nouvelles commandes/fonctionalités aux Nabaztag:tag ! A suivre...

Conclusion

A chacun désormais d'enrichir/modifier le script p.php en fonction de ses besoins...
Installation facile sur un réseau local
Beaucoup de possibilités offertes

Pour les discussions, se rendre directement sur le Nabaztag forumactif.

mardi 8 novembre 2011

Nabaztag V2 : Boot Nabizdead


Contrairement à un mode de fonctionnement normal Violet (cf post), le Nabaztag peut être modifié au démarrage pour se comporter en "mode Twitter" : c'est le lapin qui va interroger à intervalles réguliers un ou plusieurs serveurs d'informations. Il devient ainsi un simple diffuseur de flux.

  • Démarrage du Nabaztag:tag v2 : Demande (GET HTTP/1.0) du bootcode au serveur Nabizdead (ici www.nabizdead.net) :
GET /bc.jsp?v=0.0.0.10&m=00:19:xx:xx:xx:xx&l=00:00:00:00:00:00&p=00:00:00:00:00:00&h=4 HTTP/1.0
User-Agent: MTL
Pragma: no-cache
Host: www.nabizdead.net
Le serveur répond en renvoyant le fichier bootcode.bin
HTTP/1.1 200 OK
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny13 with Suhosin-Patch
amber...mind (22426 octets)

  • Le lapin est prêt à recevoir des ordres. Sa première demande est :
GET /~nabizdea/p.php?v=0.0.5&sn=0019xxxxxxxx&tp=6&ref=&rep=&r=52883&conf=1 HTTP/1.0
User-Agent: MTL
Pragma: no-cache
Host: 213.186.33.17
Le serveur répond en renvoyant un fichier de commandes en langage clair
DYN 600
TIME 37287
WAKEUP -1
SLEEP -1
SNDTHR 100
ASKDELAY 20
MSK 15
COLOR FF8000
LANG fr
RESET
SAY Me voici finalement dans mon nouveau terrier.
SAY On est bien ici. Je peux faire de nouvelles choses.
SAY Si tu m'apprivoises, tu seras pour moi unique au monde.
SAY Pour m'apprivoiser, utilise mes oreilles !
SAY Lorsque j'ai une oreille leve et une autre baisse, j'attends que tu me rpondes.
SAY Si tu lves alors les deux oreilles, tu veux me dire : oui, j'aime, encore.
SAY Si tu les baisses, je comprends : non, je n'aime pas.
SAY Par un clic simple, je te lis une information trouve sur internet.
SAY Parfois, j'en lis simplement parce que je sens ta prsence.
SAY Quand tu veux que je dorme, baisse mes deux oreilles.
SAY Quand tu veux que je me rveille, relve mes deux oreilles.
SAY Tu vois, c'est trs simple
!conf.clock.0 Il est minuit
!conf.clock.1 Il est 1 heure, j'ai un peu sommeil.
!conf.clock.2 Il est 2 heure, tu viens te coucher ?
!conf.clock.3 Il est 3 heure, si on se faisait une belote ?
!conf.clock.4 Il est 4 heure, je vais faire un caf pour tenir.
!conf.clock.5 Il est 5 heure, Paris s'veille.
!conf.clock.6 Il est 6 heure, dj rveill ?
!conf.clock.7 Il est steure.
!conf.clock.8 Il est 8 heure, c'est l'heure des pompes.
!conf.clock.9 Il est 9 heure.
!conf.clock.10 Il est 10 heure.
!conf.clock.11 Il est 11 heure.
!conf.clock.12 Il est midi, c'est ravioli.
!conf.clock.13 Il est 13 heure, Miam miam
!conf.clock.14 Il est 14 heure, tu as oubli mon calva.
!conf.clock.15 Le train de 14 heure 59 vient de partir
!conf.clock.16 Il est 16 heure, j'ai l'oreille qui me gratouye
!conf.clock.17 Il est 17 heure, soyons prcis.
!conf.clock.18 Il est 17 heure ... chez les Anglais.
!conf.clock.19 Il est 19 heure, tout simplement.
!conf.clock.20 Il est 20 heure, c'est l'heure du 20 heure.
!conf.clock.21 Il est vint une heure.
!conf.clock.22 Il est 22 zeure
!conf.clock.23 Il est 23 heure, chatouille-moi les oreilles.
!conf.wakeup C'est l'heure de rveil ! C'est une bonne journe qui démarre
!conf.sleep C'est l'heure de mon gros dodo.

  • Les autres demandes ("ping") s'enchainent ensuite régulièrement
GET /~nabizdea/p.php?v=0.0.5&sn=0019xxxxxxxx&tp=0&ref=&rep=&r=51368&conf=0 HTTP/1.0
User-Agent: MTL
Pragma: no-cache
Host: 213.186.33.17

Note : Pour ceux qui voudraient écrire eux-même leur bootcode et modifier ainsi le comportement de leur lapin, se référer aux articles disponibles ici.

jeudi 6 octobre 2011

Nabaztag V2 : Boot Process Violet


Nabaztag V2
Démarrage du Nabaztag:tag v2 : Demande (GET HTTP/1.0) du bootcode au serveur alternatif OJN (ici ojn.psnet.fr) ou au serveur d'origine Violet sur lequel est enregistré le Nabaztag:tag V2.

Dans cette configuration, le lapin va recevoir ses ordres du serveur d'applications : on est en mode "Jabber"; contrairement au serveur de type Nabizdead (mode twitter) où c'est le lapin qui demande régulièrement au serveur s'il a une action à faire.
GET /vl/bc.jsp?v=0.0.0.10&m=00:19:xx:xx:xx:xx&l=00:00:00:00:00:00&p=00:00:00:00:00:00&h=4 HTTP/1.0
User-Agent: MTL
Pragma: no-cache
Host: ojn.psnet.fr
Le serveur répond en renvoyant le fichier bootcode.bin
HTTP/1.1 200 OK
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny13 with Suhosin-Patch
Last-Modified: Sat, 17 Sep 2011 11:35:22 GMT
ETag: "2a9c1b8-190dd-4ad218151f280"
Accept-Ranges: bytes
Content-Type: text/plain
Accept-Ranges: bytes
X-Varnish: 546410822
Age: 0
Via: 1.1 varnish
Content-Length: __102621__
Accept-Ranges: bytes
Date: Sat, 15 Oct 2011 13:49:59 GMT
X-Varnish: 248892563
Age: 0
Via: 1.1 varnish
Connection: close
X-Cache: MISS
amber...mind => c'est le bootcode binaire - 101 Ko

  • Locate : Une fois le bootcode récupéré, une nouvelle demande (GET HTTP/1.0) concerne cette fois-ci le fichier de config du serveur OJN ou Violet :
GET /vl/locate.jsp?sn=0019xxxxxxxx&h=4&v=18673 HTTP/1.0
 User-Agent: MTL
 Pragma: no-cache
 Icy-MetaData:1
 Host: ojn.psnet.fr
Le serveur répond en renvoyant un fichier texte (ici 70 cars) contenant les adresses des serveurs ping broad et xmpp
HTTP/1.1 200 OK%%%
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny13 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-1+lenny13
Vary: Accept-Encoding
Content-Type: text/html
Accept-Ranges: bytes
X-Varnish: 546411214
Age: 0
Via: 1.1 varnish
Content-Length: __70__
Accept-Ranges: bytes
Date: Sat, 15 Oct 2011 13:51:31 GMT
X-Varnish: 248892606
Age: 0
Via: 1.1 varnish
Connection: close
X-Cache: MISS
ping ojn2.psnet.fr
broad ojn2.psnet.fr
xmpp_domain ojn2.psnet.fr:5222

  • Le lapin est désormais prêt à recevoir des ordres...

Note : Pour ceux qui voudraient écrire eux-même leur bootcode et modifier ainsi le comportement de leur lapin, se référer aux articles disponibles ici.

Voir aussi la doc sur le langage métal :

mardi 12 avril 2011

Karotz API - full Php Class


Karotz Php Class - Rel. 1.0b màj 24-04-2011

La version 1.0b de la "Wizz.cc Karotz Class for Php" est en ligne... On accède, au travers de cette classe, à toutes les fonctionnalités de l'Api Web du Karotz publiée par Mindscape.

Cela facilitera le développement des applis web et notamment la migration des sites Nabaztag...

Fichier Zip.

Utilisation :

1 - Inclusion : include('wizz.cc_karotz_class.php');

2 - Instanciation : $Kz = new wizz_karotz($interactiveid, true); (true or false for debug_mode)

3 - Commandes :
$result = $Kz->say('Wizz php class for karotz', 'en');
ou : echo $Kz->ears(2, 5);
ou : $Kz->led_light('FF0000');

$Kz->quit();

4 - Contrôle du résultat si nécessaire : if($Kz->get_responsecode()=='OK') echo 'Cool';

Méthodes implémentées :

$Kz->say($text, $lang)
$Kz->ears($left, $right, $relative)
$Kz->ears_reset()
$Kz->led_pulse($color, $period, $pulse)
$Kz->led_fade($color, $period)
$Kz->led_light($color)
$Kz->play($url)
$Kz->play('previous|next|pause'|'resume'|'stop')
$Kz->play('allsong::'|'title::xx'|'artist::xx'|'folder::xx'|'genre::xx')
$Kz->usb_unlock()
$Kz->usb_allsong()
$Kz->usb_folder()
$Kz->usb_artist()
$Kz->usb_genre
$Kz->usb_playlist()
$Kz->photo($url)
$Kz->video()
$Kz->chor($chor) - not yet released by the Kz DevTeam
$Kz->chor_file($url)
$Kz->chor_stop()
$Kz->config()
$Kz->quit()

Différentes informations sont accessibles : deboggage, paramètres de l'api, réponse des serveurs Karotz (VoosMsg), erreurs rencontrées... :

VoosMsg :
echo $Kz->get_voosmsgid();
echo $Kz->get_correlationid();
echo $Kz->get_interactiveid();
echo $Kz->get_responsecode();
print_r($Kz->get_api_params());
echo $Kz->get_api_response();
print_r($Kz->get_api_resp_array());
echo $Kz->get_api_error();
echo $Kz->isDebug();
echo $Kz->showDebug();

Les informations retournées peuvent changer en fonction de l'api appelée.

Un exemple complet est fourni dans le zip.

Cette classe est maintenue à jour régulièrement en fonction des publications/évolutions apportées à l'Api par Violet/Mindscape[RIP].

dimanche 10 avril 2011

Karotz SDK Javascript - Tuto de base


Karotz SDK Javascript

SDK Javascript : ma 1ère application embarquée

1 - On passe sur les créations de comptes, accès au lab, etc... acquis à ce stade sur karotz.com.

2 - Créer une application dans le Lab.

3 - Charger la version zippée (prête à l'emploi) contenant les fichiers nécessaires à l'installation de l'application embarquée sur le Karotz :

Add a new version : indiquer une note (Radio Zen 1.0) puis l'emplacement du zip

Make private pourla rendre privée dans son store et voir apparaitre le bouton Test!

cliquer sur le bouton Test! puis sur Télécharger gratuitement.

Dans le panneau de configuration qui apparait, la rendre déclenchable par un Nanoz.

Validez, le Kz flashe un instant en orange et bouge ses oreilles pour indiquer qu'il vient de se mettre à jour avec l'application.

Il n'y a plus qu'à passer le Nanoz sous le nez du Kz et l'application démarre...

Cliquer une ou deux fois sur la tête du Kz pour arrêter la radio.

Karotz_SDK_example_radiozen.zip

samedi 9 avril 2011

Karotz API Web - Webcam


On se base sur le tuto précédent pour les acquis.

1 - Votre site web fait appel à la méthode suivante pour déclencher la prise de photo :

http://www.karotz.com/api/karotz/webcam?action=photo&url=http://mywebsite/my_photo.php&interactiveid=xxx

L'url de call-back indiquée en paramètre va donc recevoir l'image envoyée par le Karotz.

2 - Installer le script suivant my_photo.php sur votre site : Zip
<?php  define('MODE_DEBUG', true);

 # Log de quelques infos...
 #
 if (MODE_DEBUG) {
if ($fh = fopen('_log.txt', 'a')) {
fwrite($fh, 'Params (key/value) : ['.PHP_OS.']'.PHP_EOL);
fwrite($fh, '--$_REQUEST--'.PHP_EOL);
foreach ($_REQUEST as $key => $value) fwrite($fh, $key.' = '.$value.PHP_EOL);
if (!empty($_FILES)) {
fwrite($fh, '--$_FILES--'.PHP_EOL);
foreach ($_FILES as $key => $value) fwrite($fh, $key.' = '.$value.PHP_EOL);
if (isset($_FILES['sendfile'])) foreach ($_FILES['sendfile'] as $key => $value) fwrite($fh, $key.' = '.$value.PHP_EOL);
}
fclose($fh);
}
 }

 # Quelques tests au cas où...
 #
 if (empty($_FILES)) exit;
 if ($_FILES['sendfile']['error'] !== UPLOAD_ERR_OK) exit; # !== not !=
 if ($_FILES['sendfile']['type'] != 'image/jpeg') exit;
 if ($_FILES['sendfile']['size'] <= 0) exit;

 # Le répertoire de destination
 # Le nom donné à l'image reçue
 #
 $udir  = 'my_dir/';
 $ufile = $udir.basename( $_FILES['sendfile']['name']);

 # Pas besoin de tester le résultat... sauf pour le logger
 #
 move_uploaded_file($_FILES['sendfile']['tmp_name'], $ufile);
?>
  • L'image est alors disponible au format jpeg (640x480, 96dpi, 24bits) dans le répertoire my_dir.
  • On pourra nommer les images à sa convenance en modifiant la variable $ufile.
Notes : Les variables transmises au script lors du callback sont les suivantes :

$_POST
filename = snapshot_2011_04_21_22_40_17.jpg
interactiveid = bfe84c04-8396-4b71-953d-3630a6963e2b
correlationid = fb68d2b9-784f-46c7-9e65-0b8252d4097e
uuid = fb68d2b9-784f-46c7-9e65-0b8252d4097e
submit = send

$_FILES
sendfile = Array
name = snapshot_2011_04_09_22_40_17.jpg
type = image/jpeg
tmp_name = /var/log/tmp/phpEZiVvU
error = 0
size = 31445

L'interactiveID récupéré permet alors de faire le lien avec l'utilisateur qui a déclenché la prise de vue.

mercredi 6 avril 2011

Karotz API Web - Tuto de base


API REST Web : Développer une application en mode Web

1 - On passe sur les créations de comptes, accès au lab, etc... acquis à ce stade sur karotz.com.

2 - Créer une application dans le Lab et noter la clé publique de l'appli générée.

3 - Copier et créer le descripteur ci-dessous (cf plus bas descriptor.xml), le zipper avec son fichier screen.xml, charger le tout -bouton "Envoyer le code"-, rendre l'application privée et la tester (acheter et installer sur le kz) -bouton "Tester"-.

Deux tags importants : <deployment> ("external" pour un site web) et <callback> qui indique l'url du site web -le vôtre- qui va récupérer les informations de session interactiveid et installid.

Ne pas oublier de modifier les tags <apikey> et <callback> avec les bonnes informations...

3b - Ftposter le script php de test sur votre serveur (cf plus bas kztest.php).

4 - Dans votre navigateur, allez à http://www.karotz.com/authentication/run/karotz/votre_api_key_récupérée_au_2
C'est aussi ce lien que l'on pourra indiquer sur un site web ou dans un mail.

5 - L'url amène alors sur karotz.com qui requiert une identification -email+pass de son compte Karotz.com-...

6 - ... qui à son tour -après validation de l'identification- renvoie sur l'url de callback saisie dans le descripteur -soit ici http://mon_site_web/kztest.php- AVEC les fameux interactiveID et installID passés en paramètres !

Conclusion : La -grosse- différence avec les Nabz est que désormais il faut s'identifier... fini le temps où il suffisait de coller un "serialnumber/token" dans la requête ! Pour le coup, cela va sembler moins ouvert à certains ;-)) ne serait-ce que pour envoyer un message à son(sa) voisin(e)... A confirmer. Mais beaucoup de possibilités offertes... à nos cla(p)viers !

NB : Après avoir énoncé son texte ou bougé les oreilles, la session peut rester activée -si l'ordre "stop" n'a pas été traité correctement pour une raison quelconque. Le Karotz clignote alors en blanc. Lui cliquer (rapidement) 3 fois sur la tête afin de lui faire reprendre ses esprits... ou attendre 15 minutes -délai actuel du timeout-.

Descripteur descriptor.xml : peut sans doute être réduit, certaines infos n'ayant pas d'intérêt pour une application "externe". Finalement le tag <api_key> n'est pas obligatoire.
 <descriptor> <name>WWW</name>
<apikey>votre_api_key_récupérée_au_2</apikey>
<version>1.0</version>
<accesses>
<access>ears</access>
<access>led</access>
<access>tts</access>
</accesses>
<editor>Bunny</editor>
        <asrName>webapi</asrName>
<deployment>external</deployment>
<interruptible>true</interruptible>
<awake>true</awake>
<callback>http://mon_site_web/kztest.php</callback>
</descriptor>
Paramètres screen.xml
<screen nanoTrigger="false"
permanentTrigger="false"
scheduledTrigger="false"
scheduledDateTrigger="false"
voiceTrigger="false">
<button label="Cliquez-ici pour lancer Mon_Appli..." link="http://www.karotz.com/authentication/run/karotz/votre_api_key_récupérée_au_2" />
</screen>
Script kztest.php
<?php
 # Wizz.cc
 # http://www.karotz.com/authentication/run/karotz/YOUR-APIKEY

 echo 'Referer:'.$_SERVER['HTTP_REFERER'].'<br>';

 $interID = $HTTP_GET_VARS['interactiveid'];
 echo 'interactiveID = ['.$interID.']<br>';
 echo 'installID = ['.$HTTP_GET_VARS['installid'].']<br>';

 # Play with Karotz
 #
 $curl = curl_init(); if (!$curl) exit;

 curl_setopt($curl, CURLINFO_HEADER_OUT, true);
 curl_setopt($curl, CURLOPT_HEADER, false);
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

 # Parler : Quoi de neuf Docteur ?
 curl_setopt($curl, CURLOPT_URL, 'http://www.karotz.com/api/karotz/tts?action=speak&lang=FR&text=quoi%20de%20neuf%20docteur&interactiveid='.$interID);
 $result = curl_exec($curl);
 # Erreur
 if (curl_errno($curl)) { $curl_error = curl_error($curl); echo '<p>Err>&nbsp;'.$curl_error.'</p>'; exit; }

 echo '<hr>';
 $curl_info = curl_getinfo($curl);
 echo '<ul><li>Request time:&nbsp;'.$curl_info['total_time'].' sec.'
. '<li>Request header:&nbsp;'.$curl_info['request_header']
. '<li>Bytes transfered:&nbsp;'.number_format($curl_info['size_download'], 0, '', ' ')
.'</ul>';

 # Decode Xml response from server
 #
 $code = '';
 if ($result!='') try {
   $xml = new SimpleXMLElement($result);
   echo '<p>Speak response:</p><pre>'; print_r($xml); echo '</pre>';
   # Le code retourné
   $code = $xml->response->code;
 } catch(Exception $e) { echo '<b>Error</b>: <font color="red">'.$e->getMessage().' (severity '.$e->getCode().')</font><br>'; }
 echo '<hr>';
 if ($code=='OK') echo '<font color="green">Cool !</font><br>';

 # Bouger les oreilles
 curl_setopt($curl, CURLOPT_URL, 'http://www.karotz.com/api/karotz/ears?left=20&right=-30&interactiveid='.$interID);
 curl_exec($curl);

 # Flash
 curl_setopt($curl, CURLOPT_URL, 'http://www.karotz.com/api/karotz/led?action=light&color=FF00FF&interactiveid='.$interID);
 curl_exec($curl);

 # Libérer le Kz au bout de 5 sec
 sleep(5);
 curl_setopt($curl, CURLOPT_URL, 'http://www.karotz.com/api/karotz/interactivemode?action=stop&interactiveid='.$interID);
 curl_exec($curl);

 curl_close($curl);
?>
Résultat :
Referer:http://www.karotz.com/login
interactiveID = [3a0ce7bc-c169-4266-ab3d-0c51d564d651]
installID = [7319bdb4-169d-4181-8cd4-fea9de4f4e9a]

Request time: 0.395879 sec.
Request header: GET /api/karotz/tts?action=speak&lang=FR&text=quoi%20de%20neuf%20docteur&interactiveid=3a0ce7bc-c169-4266-ab3d-0c51d564d651 HTTP/1.1 Host: www.karotz.com Accept: */*
Bytes transfered: 234

Speak response:
SimpleXMLElement Object
(
    [id] => eb310b17-a77e-4cfb-ad21-a99c114a52eb
    [correlationId] => 2e6fa6a2-f2a8-4795-b20c-c6366c001adb
    [interactiveId] => 3a0ce7bc-c169-4266-ab3d-0c51d564d651
    [response] => SimpleXMLElement Object
        (
            [code] => OK
        )
)