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.