Piloter les modules Yoctopuce à la dure

Piloter les modules Yoctopuce à la dure

Il pourrait arriver qu'un jour vous deviez, pour une application donnée, vous passer de notre librairie de programmation à haut niveau. Par exemple parce que vous devez les piloter avec un langage que nous ne supportons pas (encore), ou parce que vous ne voulez pas vous encombrer de programmation par objets. C'est tout à fait possible, et voici les clés pour y parvenir.



Au plus bas niveau, la communication avec les modules Yoctopuce se fait en utilisant des paquets USB de type HID. Il est peut probable que vous vouliez descendre si bas, mais si le détail de notre protocole HID vous intéresse, allez jeter un coup d'oeil dans le fichier ydef.h, que vous trouverez dans le répertoire yapi de la librairie C++ ou Objective-C.

A une échelle plus intéressante, ce que nous transférons dans les paquets USB est essentiellement du trafic au format HTTP, le protocole utilisé par tous les serveurs web. Chacun de nos modules se comporte comme un petit serveur web, auquel on peut lire et changer son état par certaines URLs prédéfinies. Donc pour discuter directement avec nos modules, il faut
1) savoir envoyer une requête HTTP sur notre canal USB
2) savoir comment sont organisées les URLs de nos modules pour accéder à la fonction désirée
3) savoir à quel format nous retournons les données descriptives

Pour envoyer une requête HTTP sur notre canal USB, il y a deux possibilités. La plus simple consiste à utiliser le VirtualHub, qui est en réalité une simple passerelle TCP vers USB, et rend donc directement accessible sur le réseau le serveur web intégré de chaque module. Cela permet d'utiliser n'importe quelle librairie client HTTP pour discuter avec les modules connectés, y compris dans les langages ne disposant d'aucun support bas niveau. La seconde consiste à envoyer la requête directement en USB, à l'aide de notre fonction yapiHTTPRequest, disponible dans la librairie yapi.dll (yapi.so pour Unix). Son utilisation est détaillée un peu plus bas.

Pour organiser les URLs de nos modules, nous utilisons une architecture de type REST: l'organisation hiérarchique des URLs suit directement l'organisation logique du module, de ses fonctions et de ses attributs. Il suffit donc d'explorer avec un navigateur internet notre API REST pour trouver en quelques instants quelle est l'URL qui permet d'accéder à un relais ou à un capteur donné. Pour ce faire, lancez le VirtualHub, cliquez sur le numéro de série du module qui vous intéresse et ouvrez le lien intitulé Open API browser.

Le lien pour ouvrir l'API REST, bon point de départ pour faire des expériences
Le lien pour ouvrir l'API REST, bon point de départ pour faire des expériences



Vous verrez ainsi que pour commuter le relais 1 d'un module à l'état actif, il suffit de d'accéder à l'URL:

/api/relay1?state=1


De même, pour lire la valeur en Lux d'un capteur de lumière, il suffit de lire le contenu de l'URL

/api/lightSensor/currentValue


Si vous voulez accèder a un module spécifique par son numero de série, il suffit d'ajouter le numéro de série dans le path de l'URL:

/bySerial/RELAYHI1-00044/api/relay1?state=1


Vous pouvez aussi utiliser le nom logique de votre module: imaginons un module nomé MonModuleAMoi, vous pouvez alors l'accéder de la manière suivante:

/byName/MonModuleAMoi/api/relay1



Pour lire l'état de tous les senseurs d'un module en une seule requête, on peut charger directement l'URL la plus haute. Mais dans ce cas le résultat est une structure de données, qu'il faudra parser pour retrouver les différents capteurs. Le choix du format de représentation structuré se fait à l'aide de l'extension demandée sur l'URL. Par exemple:
/api.json retourne une structure décrivant tout le module, encodée en JSON.
/api.xml retourne la même structure, mais encodée en XML.
/api.txt retourne la même structure, mais en simple texte

Changer l'état d'un relais à l'aide du virtual hub et d'une simple requête  HTTP
Changer l'état d'un relais à l'aide du virtual hub et d'une simple requête HTTP



La liste de attributs disponibles pour chaque module est décrite au début du chapitre programmation du manuel de chaque module.

Si vous voulez un exemple d'utilisation assez poussé de cette technique, vous pouvez aller voir le projet Yocto-Meteo sur blogspot fait par un de nos utilisateurs en Java, utilisant sa propre version des objets pour communiquer aux modules en utilisant l'API REST (la notre devrait suivre sous peu...) et les géolocaliser.

Voyons maintenant les fonctions que nous fournissons pour accéder directement à notre canal HTTP par USB, sans utiliser le VirtualHub. Il s'agit de notre librairie appelée yapi. Son code source est disponible dans les librairies C++ et Objective-C, et les librairies dynamiques pré-compilées sont présentes par exemple dans les librairies C#, VisualBasic et Delphi.

Le première fonction à appeler une (et une seule) fois est yapiInitAPI:

int yapiInitAPI(int connection_type, char *errmsg);


Passez la valeur 1 au paramètre connection_type pour utiliser USB.
Passez un tampon de 255 caractères au paramètre errmsg afin que l'API puisse vous retourner un message d'erreur en cas de problème. Vous pouvez passer un pointeur nul si vous ne le désirez pas.
La fonction retourne un entier négatif en cas d'erreur, ou zéro si tout se passe bien.

La deuxième fonction à appeler au moins une fois (et périodiquement si vous voulez supporter le hot-plug) est yapiUpdateDeviceList.

int yapiUpdateDeviceList(int forceupdate, char *errmsg);


Passez la valeur 1 au paramètre forceupdate pour forcer un scan matériel.
Passez un tampon de 255 caractères au paramètre errmsg afin que l'API puisse vous retourner un message d'erreur en cas de problème. Vous pouvez passer un pointeur nul si vous ne le désirez pas.
La fonction retourne un entier négatif en cas d'erreur, ou zéro si tout se passe bien.

Ensuite, vous pouvez simplement appeler yapiHTTPRequest pour discuter avec le module:

int yapiHTTPRequest(char *device, char *request, char* buffer,int buffsize,
                    int *fullsize, char *errmsg);


Passez le numéro de série ou le nom logique du module désiré au paramètre device.
Passez la requête HTTP complète (y compris les sauts de ligne terminaux) au paramètre request.
Passez un tampon suffisamment grand pour recevoir la réponse au paramètre buffer, et indiquez sa taille au paramètre buffsize.
Passez un pointeur vers un entier au paramètre fullsize afin que l'API puisse vous retourner la taille effective de la réponse. Vous pouvez passer un pointeur nul si vous ne désirez pas connaître la taille de la réponse. Vous pouvez de toute façon vous fier au fait que la réponse sera terminée par un caractère nul.
Passez un tampon de 255 caractères au paramètre errmsg afin que l'API puisse vous retourner un message d'erreur en cas de problème. Vous pouvez passer un pointeur nul si vous ne le désirez pas.
La fonction retourne un entier négatif en cas d'erreur, ou zéro si tout se passe bien.

Voici un petit exemple en C "pur sucre" pour commuter un relais:

#include <stdio.h>
#include "yapi.h"

int main(int argc, char *argv)
{
   char errmsg[256];
   char buffer[256];

   if(yapiInitAPI(1, errmsg) < 0 || yapiUpdateDeviceList(1, errmsg) < 0) {
      fprintf("init error: %s\n", errmsg);
      return 1;
   }

   if(yapiHTTPRequest("RELAYLOH1-000001",
                      "GET /api/relay1.json?state=0 HTTP/1.1\r\n\r\n",
                      buffer, sizeof(buffer), NULL, errmsg) < 0) {
      fprintf("communication error: %s\n", errmsg);
      return 1;
   }
   return 0;
}



Il existe encode de nombreuses fonctions dans l'interface de bas niveau, permettant des accès non bloquant, des callbacks, etc. Pour en savoir plus, il suffit d'ouvrir le fichier yapi.h: les fonctions utiles y sont en principe raisonnablement commentées. Et si jamais, cela ne suffit pas, vous pouvez laisser un commentaire sur cet article ou nous envoyer un email à l'adresse support@yoctopuce.com.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.