Commander un Arduino avec une tablette Android
- Etude de cas -
V. Les entités du serveur▲
Revenons à l'architecture de notre application client / serveur. L'architecture du serveur est la suivante :
La couche [DAO] va communiquer avec les Arduinos. Elle va échanger avec elle des lignes de texte JSON. Côté serveur, ces lignes de texte vont être transformées en objets que nous présentons maintenant. Par ailleurs, le serveur échange également avec ses clients (Android ou web) des objets. Nous les appellerons des entités. Elles sont présentées maintenant et vous seront fournies :
en [1], le projet Eclipse des entités ;
en [2], c'est un projet Maven. Il n'y a qu'une dépendance, celle sur la bibliothèque JSON Gson de Google [4] ;
en [3], les entités ;
La couche [DAO] envoie à l'Arduino des commandes et en reçoit des réponses. Ces deux entités sont représentées par les classes [Commande] et [Reponse].
V-A. La classe [Commande]▲
C'est la suivante :
Sélectionnez 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.
package
istia.st.domotique.entities;
...
public
class
Commande implements
Serializable {
private
static
final
long
serialVersionUID =
1L
;
private
String id;
private
String action;
private
Map<
String, Object>
parametres;
private
Map<
String, Object>
map =
new
HashMap<
String, Object>
(
);
public
Commande
(
) {
}
public
Commande
(
String id, String action, Map<
String, Object>
parametres) {
this
.id =
id;
this
.action =
action;
this
.parametres =
parametres;
map.put
(
"
id
"
, id);
map.put
(
"
ac
"
, action);
map.put
(
"
pa
"
, parametres);
}
@
SuppressWarnings
(
"
unchecked
"
)
public
Commande
(
String json) throws
Exception {
Map<
String, Object>
map =
new
Gson
(
).fromJson
(
json, new
TypeToken<
Map<
String,Object>
>
(
) {
}
.getType
(
));
this
.id =
(
String) map.get
(
"
id
"
);
this
.action =
(
String) map.get
(
"
ac
"
);
this
.parametres =
(
Map<
String, Object>
) map.get
(
"
pa
"
);
}
@
Override
public
String toString
(
) {
try
{
return
new
Gson
(
).toJson
(
this
);
}
catch
(
Exception e) {
return
"
Problème
de
conversion
en
JSON
:
"
+
e;
}
}
public
String toJson
(
) throws
IOException {
return
new
Gson
(
).toJson
(
map);
}
...
}
On se rappelle que les lignes JSON envoyées à l'Arduino sont de la forme :
Sélectionnez 1.
{
"
id
"
:"
...
"
,"
ac
"
:"
...
"
,"
pa
"
:{
...}
}
[id] est l'identifiant de la commande ;
[ac] est le nom de l'action à exécuter ;
[pa] est un dictionnaire listant les paramètres de l'action ;
Les trois paramètres [id, ac, pa] sont définis aux lignes 8-10 de la classe. Si on sérialise en JSON cette classe on aura une chaîne comme suit :
Sélectionnez 1.
{
"
id
"
:
"
...
"
,
"
action
"
:
"
...
"
,
"
parametres
"
:
{
.
.
.
}
}
Parce que l'Arduino a très peu de mémoire, on ne peut envoyer cette chaîne trop longue. On décide donc d'envoyer celle montrée plus haut. Pour cela, on crée dans la classe un dictionnaire avec les attributs [id, ac, pa]. Il est défini ligne 11. Lorsqu'on voudra envoyer une commande, c'est la chaîne JSON de ce dictionnaire qui sera envoyée.
ligne 30 : la classe possède un constructeur qui accepte pour paramètre la chaîne JSON d'un dictionnaire ayant les attributs [id, ac, pa] ;
ligne 52 : lorsqu'on veut envoyer la chaîne JSON de la commande, c'est celle de son dictionnaire interne qui sera envoyée (ligne 54) ;
ligne 41 : la méthode [toString] rend la chaîne JSON de la classe ;
V-B. La classe [Reponse]▲
C'est la suivante :
Sélectionnez 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55.
package
istia.st.domotique.entities;
...
public
class
Reponse implements
Serializable {
private
static
final
long
serialVersionUID =
1L
;
private
String json;
private
String id;
private
String erreur;
private
Map<
String, Object>
etat;
public
Reponse
(
) {
}
public
Reponse
(
String json, String id, String erreur, Map<
String, Object>
etat) {
this
.json =
json;
this
.id =
id;
this
.erreur =
erreur;
this
.etat =
etat;
}
@
SuppressWarnings
(
"
unchecked
"
)
public
Reponse
(
String json) {
Map<
String, Object>
map =
null
;
try
{
map =
new
Gson
(
).fromJson
(
json, new
TypeToken<
Map<
String, Object>
>
(
) {
}
.getType
(
));
this
.id =
(
String) map.get
(
"
id
"
);
this
.erreur =
(
String) map.get
(
"
er
"
);
this
.etat =
(
Map<
String, Object>
) map.get
(
"
et
"
);
}
catch
(
Exception ex) {
this
.json =
json;
this
.erreur =
"
json
invalide
"
;
}
}
@
Override
public
String toString
(
) {
try
{
return
new
Gson
(
).toJson
(
this
);
}
catch
(
Exception e) {
return
"
Problème
de
conversion
en
JSON
:
"
+
e;
}
}
...
}
L'Arduino renvoie des lignes JSON de la forme :
Sélectionnez 1.
{
"
id
"
:
"
2
"
,
"
er
"
:
"
303
"
,
"
et
"
:
{
}
}
ou
Sélectionnez 1.
{
"
id
"
:
"
4
"
,
"
er
"
:
"
0
"
,
"
et
"
:
{
"
pin0
"
:
"
1023
"
}
}
[id] est l'identifiant de la commande à laquelle on répond ;
[er] est un code d'erreur ;
[et] est un dictionnaire listant les résultats de l'action ;
Les attributs [id, er, et] sont définis lignes 10-12 de la classe.
ligne 26 : l'objet [Reponse] est construit à partir de la chaîne JSON envoyée par l'Arduino ;
lignes 27, 30 : on construit d'abord un dictionnaire ;
lignes 32-34 : l'objet [Reponse] est construit ensuite à partir de ce dictionnaire ;
ligne 35 : si la chaîne JSON envoyée par l'Arduino n'a pas pu être parsée, on aura une exception ;
ligne 36 : on mémorise alors la chaîne JSON invalide dans le champ de la ligne [9] ;
ligne 44 : la méthode [toString] affiche la chaîne JSON de l'objet. On aura donc ainsi la chaîne JSON invalide si ce cas se produit ;
V-C. La classe [Arduino]▲
On se rappelle que l'Arduino, en s'enregistrant auprès de la couche [DAO] envoie la chaîne d'identification suivante :
Sélectionnez 1.
{
"
id
"
:
"
192.168.2.3
"
,
"
desc
"
:
"
duemilanove
"
,
"
mac
"
:
"
90:A2:DA:00:1D:A7
"
,
"
port
"
:
102
}
On enregistre ces informations dans la classe [Arduino] suivante :
Sélectionnez 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
package
istia.st.domotique.entities;
import
java.io.Serializable;
public
class
Arduino implements
Serializable{
private
static
final
long
serialVersionUID =
1L
;
private
String id;
private
String description;
private
String mac;
private
String ip;
private
int
port;
public
String toString
(
) {
return
String.format
(
"
id=[%s],
description=[%s],
mac=[%s],
ip=[%s],
port=[%s]
"
, id, description, mac, ip, port);
}
...
}
les informations des lignes [9-11,13] sont tirées de la ligne envoyée par l'Arduino ;
la ligne 12 qui représente l'IP de l'Arduino sera renseignée par le serveur d'enregistrement qui traite la connexion de l'Arduino ;
V-D. La classe [DomotiqueException]▲
Les différentes couches du serveur lanceront des exceptions non contrôlées par le compilateur de type [DomotiqueException] :
Sélectionnez 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44.
package
istia.st.domotique.entities;
import
java.io.Serializable;
public
class
DomotiqueException extends
RuntimeException implements
Serializable{
private
static
final
long
serialVersionUID =
1L
;
private
int
code =
0
;
public
DomotiqueException
(
) {
super
(
);
}
public
DomotiqueException
(
String message) {
super
(
message);
}
public
DomotiqueException
(
String message, Throwable cause) {
super
(
message, cause);
}
public
DomotiqueException
(
Throwable cause) {
super
(
cause);
}
public
DomotiqueException
(
String message, int
code) {
super
(
message);
setCode
(
code);
}
public
DomotiqueException
(
Throwable cause, int
code) {
super
(
cause);
setCode
(
code);
}
public
DomotiqueException
(
String message, Throwable cause, int
code) {
super
(
message, cause);
setCode
(
code);
}
...
}
C'est une classe d'exception standard si ce n'est qu'elle encapsule un code d'erreur, ligne 9.
Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
2013 Serge Tahé. Aucune reproduction, même partielle, ne peut être
faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à
trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.