Service Agenda pour Habitat Intelligent

De fablab
Aller à : navigation, rechercher

Cadre du projet

  • Encadrants : Cédric Gérard et Stan Borkowski
  • Nombre d'étudiants : 2 à 4
  • Lieu : le projet aura lieu dans la salle FabLab de l'Ensimag.
  • Prérequis : programmation Java

Contexte

L’objectif de ce projet est de prototyper un nouveau service pour habitat intelligent de façon à pouvoir contrôler certaines fonctions de la maison à partir d’un agenda en ligne (par exemple Google Agendda). Grâce à ce service, l’habitat intelligent pourra :

  • afficher les agendas des habitants sur un écran permanent (e-ink)
  • interpréter les entrées des agendas pour contrôler les équipements présents dans la maison (par exemple, lancer l’enregistrement d’un programme télé même si les habitants sont absents, lancer la machine à laver le linge, etc.)
  • fournir des services d’aide au cas où un ré-ajustement des agendas des membres de la famille est nécessaire en raison d’un évenemenet imprévu (par exemple, l’enfant est malade, les rendez-vous des parents doivent être modifiés : alors le système peut proposer des solutions répondant à la situation).

Ce travail sera réalisé en lien avec le projet européen AppsGate (la future set-top-box pour maison intelligente) et l’EquipEx Amiqual4Home.

Travail demandé

Le travail porte sur la conception et la mise en œuvre d’un démonstrateur illustrant l’usage d’un agenda dans un habitat intelligent.Voici les étapes du travail :

  • Développement d’un bundle (service) logiciel agenda ICalendar.
  • Configuration d’un lecteur numérique e-ink en tant qu’afficheur permanent des agendas.
  • Création en impression 3D d’une coque permettant de fixer avec des aimants le lecteur e-ink sur une surface métallique (sur un réfrigérateur)
  • Prise en main des services multimédia UPnP (MediaRenderer, MediaServer)
  • Développement du “cerveau” de la maison ; d’un module qui s’abonne aux événements des agendas et qui contrôle le (ou les) dispositif(s) UPnP.

Détails techniques

La programmation se fera en Java en utilisant les frameworks OSGi et iPOJO.La configuration du lecteur e-ink nécessite la connaissance de Linux et peut demander l’utilisation d’un microcontroleur, l’objectif étant de maximiser le temps de fonctionnement du dispositif tout en permettant des mises à jour fréquentes de l’affichage.

Logiciels

  • Framework OSGi avec IPOJO (Felix)
  • UPnP: UPnP MediaServer avec les services ContentDirectory et ScheduledRecording.
  • Bundle OSGi UPnP base driver (Apache)


Service agenda:


Environnement de développement:

  • Eclipse ou Netbeans avec Maven
  • Déploiement sous framework OSGi


PRESENTATION DU PROJET

Ce projet s’insère dans le cadre du projet d'envergure européenne AppsGate qui a pour but de trouver des solutions pour améliorer la qualité de vie en se basant sur les nouvelles technologies. Ainsi l'une des pistes de recherche du projet AppsGate est de trouver des solutions innovantes pour les habitats du futur. Ce type de projet de recherche voit le jour en raison de l’émergence des technologies connectées.

C'est dans ce contexte qu'on nous a confié ce projet de spécialité qui vise à concevoir un dispositif d'agenda intelligent dans le but de faciliter la gestion du quotidien familial mais également de programmer des équipements électroniques de la maison à partir de son agenda personnel.

Il nous est ainsi demandé d'implémenter les services suivants :

  • récupération d'agendas google personnels et conversion au format standard iCal afin de disposer de la librairie associée pour les manipuler facilement.
  • création d'un agenda commun à toute la famille dans lequel il est possible d'ajouter et de supprimer des tâches. Chaque tâche pouvant être attribuée à une voire plusieurs personnes.
  • gestion des conflits entre les tâches (e.g. plusieurs tâches demandent la participation d'une même personne au même moment), gérer les rappels éventuels d'un événement.
  • afficher les différents agenda sur un afficheur permanent (utilisation d'une kindle).
  • mettre à jour les données sur le dispositif d'affichage.

Notre dispositif est donc clairement orienté services et sur les conseils de nos tuteurs nous avons implémenté des composants offrant chacun un ou plusieurs services distincts. Pour cela nous avons développé notre application dans l'environnement OSGI qui correspond à nos besoins car il est orienté composants et se charge de gérer les dépendances entre ceux-ci.

Nous avons adopté l'architecture suivante sous OSGI :

Architecture.png

PRESENTATION DE L'EQUIPE

Nous sommes un groupe de quatre étudiants à effectuer ce projet. Tous issus de la filière Télécom et de première année Phelma, nous nous connaissions déjà bien avant de commencer ce projet, ce qui explique notamment pourquoi ce projet a bien fonctionné.

Les domaines que nous avons découverts à l'Ensimag cette année et qui nous ont été indispensables dans la réalisation du projet sont la programmation en Java (pour l'implémentation des composants) ainsi que le développement web (pour la réalisation de l'interface utilisateur). En revanche, l'environnement OSGI et l'architecture orientée composants était pour nous une totale nouveauté.

De plus, bien que nous ayons eu un premier contact avec l'outil Maven lors de nos TP de développement web, ce projet réalisé avec Maven a été l'occasion pour nous de nous familiariser avec cet outil.

PRISE EN MAIN D'IPOJO

Pour utiliser l'architecture OSGi nous avons utiliser le framework iPOJO. Nous allons détailler ici quels sont les tutoriels et sites qui nous ont permis de rapidement comprendre son fonctionnement.


Le tutoriel iPOJO in 10 minutes (qui ne vous prendra surement pas 10 minutes..) donne un exemple d'utilisation de 2 composants iPOJO ("dictonnary" et "SpellChecker"),il ne faut pas trop s'attarder sur Ant, car même si ce tutoriel compile avec Ant dans la suite du projet nous utiliserons maven qui gère très bien les dépendances avec le pluggin iPOJO(et nous décharge de la tâche).
Ensuite le tutoriel Hello World nous montre justement un cas d'utilisation de maven pour compiler un projet et permet de comprendre un peu plus comment nous indiquons les dépendances entre bundle à l'aide des fichiers metadata.xml. Cependant nous vous déconseillons de trop vous focaliser sur la syntaxe des metadata.xml car il existe un pluggin 'Maven-Annotations' disponnible ici et qui permet de remplacer les metadata.xml par des annotations dans le code.Vous pouvez tester ces annotations sur le tutoriel de hello world que vous avez (normalement) déjà fait ici.
Grâce à ces 2 premiers tuto on peut mieux comprendre comment est organisé un projet iPOJO.Chaque module comprend un fichier pom.xml qui indique les options de compilation de maven et à la source du projet il y a un autre fichier pom.xml qui permet de lancer la compilation de tout les modules du projet. Le meilleur moyen de comprendre comment construire un fichier pom.xml est de loin d'essayer d'en écrire un à la main.
Pour finir la prise en main le tutoriel hotdog vendor vous permet d'aller plus loin dans iPOJO.

REMARQUE SUR LA GESTION DU TEMPS

Notre dispositif étant basé sur la manipulation d'agenda la gestion du temps est un point essentiel du projet.

  • La classe java.util.Date :

Tout d'abord il faut noter que la plupart des constructeurs et des méthodes de la class java.util.Date sont dépréciées. Ceci en raison d'une mauvaise implémentation par Sun (mauvaise gestion des timezones, passage à l'heure d'été ou hiver, variation des calendriers). Pour autant la class java.util.Date n'est pas vouée à disparaître. En effet elle reste et restera fonctionnelle comme étant une simple référence temporelle correspondant au nombre de millisecondes écoulées depuis le 1er janvier 1970 UTC qui est la référence des temps choisie par Unix (appelée Epoch). Elle est d'ailleurs très utilisée par les méthodes (et constructeurs) de la librairies iCal4J qui manipulent les agendas. Ainsi manipuler des java.util.Date implique de concevoir le temps comme le nombre de millisecondes écoulées depuis l'Epoch. Proscrire tout autre conception du temps telle que la conception calendaire (Year, Month, Day, Hour, Minute, Second) qui est dépréciée pour cette classe. Par conséquent l'objet Date est indépendant de la timezone de l'OS (puisque ça représente le temps absolu depuis l'Epoch) bien que la méthode toString() prenne en compte la timezone de l'OS.

  • La classe abstraite java.util.Calendar et son implémentation java.util.GregorianCalendar :

Cette classe abstraite prévoit une implémentation qui correspond à une vision calendaire du temps, a priori plus intuitive pour le programmeur. Ainsi l'équivalent du constructeur de date déprécié suivant :

Date(int year, int month, int day)

devient

Date date = null;
Calendar calendar = GregorianCalendar.getInstance();
calendar.set(year, month, day);
date = calendar.getTime();

Ce procédé est certes plus fastidieux mais il est plus en accord avec notre conception du temps et de toute manière si l'API peut sembler plus compliquer au premier abord c'est parce que la conception humaine du temps est elle même compliqué. En effet nous possédons plusieurs types de calendrier, le calendrier grégorien étant le plus connu dans le monde occidental. Ce calendrier grégorien est décomposé en plusieurs mois qui n'ont pas tous la même durée, tout comme les jours qui peuvent durée 23 ou 25 heures pendant les passages à l'heure d'été ou d'hiver. Et de plus à un instant précis l'heure n'est pas la même(date) sur toute la terre. Et c'est tout cela qui est pris en compte dans cette API.

  • La classe abstraite java.text.DateFormat et son implémentation java.text.SimpleDateFormat :

C'est l'API référence pour afficher une date. Les différents formatages possibles tirés de la javadoc sont les suivants :

DateFormat.PNG

Exemple d'utilisation :

//Choix du format :
DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
//Création d'une chaîne de caractère représentant la date actuelle au format voulu
String rightNow = dateFormat.format(new java.util.Date(System.currentTimeMillis()));

On peut noter l'utilisation d'un objet Date par la méthode format() de l'objet DateFormat.

FONCTIONNEMENT DE L'API ICAL4J

L'API iCal4J regorge de classes de toutes sortes de telle sorte que la prise en main nécessite un temps d'adaptation pour appréhender le rôle de chaque classe. L'objet de cette partie est d'expliciter l'intérêt des principales classes ainsi que la manière dont elles sont agencées entre elles.

  • La classe net.fortuna.ical4j.model.Calendar :

C'est la classe encapsulante qui représente l'agenda. Elle contient essentiellement une liste d'objet de type Component.

  • La classe net.fortuna.ical4j.model.component.VEvent :

Cette classe implémente la classe abstraite net.fortuna.ical4j.model.CalendarComponent qui elle même implémente net.fortuna.ical4j.model.Component. Cette classe représente les événements qu'on insère dans l'agenda. Il existe d'autres classes qui implémente CalendarComponent et qu'on peut théoriquement insérer dans un Calendar. Toutefois lors de la récupération des agendas google nous avons récupéré uniquement des VEvent. Nous avons donc considéré que tous les Component manipulés étaient du type VEvent. A un événement peut être associé des rappels. C'est pourquoi un VEvent possède un attribut de type ComponentList qui recense toutes les alarmes de cet événement. Une alarme est du type net.fortuna.ical4j.model.component.VAlarm. La classe VAlarm implémente également CalendarComponent, c'est pourquoi l'attribut est du type ComponentList.

  • La classe net.fortuna.ical4j.model.component.VAlarm :

Comme mentionné ci-dessus cette classe implémente CalendarComponent et donc Component. Il y a deux manière équivalente de programmer une alarme. La première est de créer un objet VAlarm à partir d'une durée relative au début de l'événement. Dans ce cas de figure on utilise le constructeur VAlarm(Dur trigger), l'objet Dur contenant dans notre cas une durée négative (puisque l'on souhaite que l'alarme se déclenche avant le début de l'événement). L'autre manière est de construire l'objet VAlarm à partir de la date de déclenchement de l'alarme. Dans ce cas on utilise le constructeur VAlarm(DateTime trigger). Il faut remarquer que dans cette solution, l'attribut duration retourné par la méthode getDuration() de l'objet VAlarm créé est null puisque non communique à la création de l'objet.

  • La classe abstraite net.fortuna.ical4j.model.component.Property :

Comme toutes classes implémentant Component un VEvent possède des objets de type Property. Il y a beaucoup de classes qui implémentent Property. Comme leur nom l'indique elles représentent les propriétés de l'événement associé. Ci-dessous les propriétés principales :

Action : associé à un VAlarm. Représente l'action à faire lors du déclenchement de celle-ci (e.g. email, dispay...)
Attendee : représente les participants à l'événement. Un participant est relié à un objet URI qui permet de stocker son adresse mail.
DtEnd : stocke la date de fin de l'événement.
DtStart : stocke la date de début de l'événement.
Summary : contient le nom de l'événement.
Uid : identifie de manière unique l'événement.
  • La classe abstraite net.fortuna.ical4j.model.component.Parameter :

Chaque objet de type Property contient une liste d'objet de type Parameter. Là encore il existe de nombreuses classes qui l'implémentent. Parmi elles, la seule qui nous a intéressé est la classe Cn (Common Name) qui associe un nom à une une Property. C'est cet objet qui nous permet de stocker le nom d'un participant.

JOURNAL DE BORD DU PROJET

Nous avons décidé tout au long du projet de tenir à jour notre journal de bord du projet qui aura pour but de montrer nos avancés jour par jour et aussi de mettre en avant quels difficultés nous rencontrons afin de conseiller d'éventuels lecteurs.

Vendredi 24 Mai :


  • Pour un 1er contact avec iPOJO: le site suivant définit bien iPOJO et offre la possibilité de suivre des tutoriels pour se lancer...
IPOJO
  • A propos de la liseuse kindle:

L'objectif concernant la liseuse étant de détourner l'utilisation standard de la Kindle pour en faire un dispositif d'affichage des agendas facile à lire et capable de fonctionner plusieurs jours sans recharge (une semaine serait l'idéal). Parmi toutes les liseuses disponibles le choix s'est porté sur la Kindle Paperwhite en raison de son écran E-Ink. Cette technologie rend la consommation de l'écran nulle tant que celui-ci ne change pas, cela correspond bien à l'utilisation que nous voulons en faire car entre chaque synchronisation (donc la majorité du temps) l'affichage sera fixe.
Le navigateur web installer de base sur le dispositif d'Amazon ne permettant pas un affichage plein écran, nous utiliserons un add-on basé sur celui-ci mais autorisant l'affichage plein écran. Pour optimiser les performances de la Kindle et donc son autonomie nous nous appuierons sur l'EventHandler qui permet l'exécution de scripts à des moments clés comme l'allumage, l'entrée et la sortie de veille. Nous serons donc en mesure de lancer immédiatement à l'allumage de la liseuse le navigateur web, puis une fois la page chargée de le mettre en veille en prévoyant le moment de sa sortie de veille pour actualiser l'affichage, la Kindle répétant en boucle ces opérations.

  1. Voici un forum fréquenté par des "développeurs Kindle". Beaucoup d'infos diverses, communauté réactive !
  2. Et voici les threads que nous allons utiliser pour rendre la liseuse utilisable :


Lundi 3 Juin :
  • GitHub:

Afin que vous puissiez suivre nos avancées, un lien vers notre git :

ICI
  • Liseuse Kindle:

Nous avons dû changer de stratégie, le problème venant du fait qu'une fois la liseuse en veille,il n'existe pas de moyen de la faire sortir de veille sans intervention physique.
Nouvelle stratégie:

  1. écran "éteint" au démarrage et lancement du navigateur ;
  2. une fois la page chargée, désactivation du WiFi et abaissement de la fréquence du processeur au minimum ;
  3. une fois la temporisation écoulée, le Kindle relance le processeur, ré-active le WiFi et actualise la page puis recharge l'état précédent ;
  4. etc...

Les outils utilisés sont les mêmes, mais différemment.
Voici quelques liens utiles en plus :

Eteindre les LEDs de l'écran
Gérer la fréquence du processeur

Pour les sources (add-on et scripts), rendez-vous sur le Git !
Concernant l'utilisation de la batterie, celle-ci semble tenir. Pour l'instant nous n'avons pu effectuer des tests uniquement sur une demie-journée, avec une synchronisation toute les heures. En extrapolant nos résultats le dispositif semble à même de tenir 6 jours sans être rechargé, ce qui est plutôt bon signe. Nous effectuerons des tests sur une durée plus prolongée pour s'assurer de cela.


Mardi 4 Juin :
  • Découverte d'iPOJO cf. "Prise en main d'iPOJO". Nous nous sommes mis tous les quatres sur ce point afin de comprendre le plus rapidement le fonctionnement d'iPOJO et de pouvoir ensuite nous lancer dans le projet.


Mercredi 5 Juin :
  • Environnement de travail :

Après avoir passer plus de deux jours à essayer de concilier l'utilisation d'Eclipse, de Maven, d'iPojo et le Git, nous n'obtenons toujours pas de résultats. Devant la durée très courte du projet et du travail à réaliser dans ce laps de temps nous décidons de laisser Eclipse de coté. Ce choix a été compliqué à prendre car nous nous passerons donc de toutes les fonctionnalités offertes par Eclipse rendant le développement en Java particulièrement simple. L'avantage étant que le projet n'est pas extrêmement gros, nous ne risquons pas trop d'être perdu entre nous différents composants, l'inconvénient majeur est que nous allons être confronté à l'utilisations de nombreuses librairies que nous ne connaissons pas, nous risquons donc de parfois perdre du temps sur des problèmes d'import, d'héritage, choses que Eclipse nous aurait évité.

  • Premier incrément :

Après l'étude des tutoriels nous avons décidé de mettre en pratique et de créer nous même nos premiers composants. Dans un premier temps notre objectif était de réaliser un premier incrément en créant l'ensemble de l'architecture du projet avec tous les composants, et de les faire communiquer de manière élémentaire en transmettant simplement des chaînes de caractères. En procédant ainsi on règle tous les problèmes de communication, d'établissement de services et de dépendances entre nos composants dès le début. Il n'y a ensuite plus qu'à améliorer les fonctionnalités de chaque composants de manière incrémentales. Nos composants sont les suivants :

  • googleAgenda : récupère le/les agenda(s) google
  • iCal4J : fournit une librairie permettant de convertir les agenda au format ical.
  • localAgenda : fusionne les différents agenda distants en local en permettant l'ajout de tâches communes à tous
  • brainModule : contrôle l'intégrité de l'agenda local et alerte les usagers sur la kindle
  • webServer : récupère régulièrement les informations sur l'agenda local pour les transmettre à la kindle sous forme d'image. Le webServer a la capacité de créer des tâches locales sur l'agenda local.

A ce jour nous avons établi toutes les liaisons nécessaires entre les composants.
Note pour le bundle iCal4J : pour permettre son utilisation il faut :

  • Intégrer les deux bundles suivants "commons-logging-1.1.2.jar" et "commons-lang3-3.1.jar"
  • Ajouter la dépendance suivante dans le fichier POM
<dependency>
 <groupId>org.mnode.ical4j</groupId>
 <artifactId>ical4j</artifactId>
 <version>2.0-beta1-SNAPSHOT</version>
</dependency>
  • Ajouter le répertoire suivant au fichier POM
<repository>
 <id>ical4j-repository</id>
 <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
 <snapshots>
 <enabled>true</enabled>
 </snapshots>
</repository>


Jeudi 6 Juin :
  • Récupération des agendas Google :

Nous nous attelons aujourd'hui à la récupération des agendas Google.

  • Découverte des bibliothèques de gestion des calendriers et des types date.
  • Serveur Web :

Nous avons compléter l'implémentation du composant "WebServer" en ajoutant les fonctionnalités suivantes :

  1. Des threads permettant d'exécuter nos actions de synchronisation.
  2. Un Timer pour lancer nos threads périodiquement, ce qui permet au composant de récupérer en temps voulu l'agenda local, de façon à être systématiquement à jour, indépendamment des requêtes de la kindle.
    • Objets utilisés : Timer, TimerTask.
  3. Le server en lui-même, ainsi qu'une servlet destinée à répondre aux requêtes de mise à jour envoyées par le kindle. Une seule servlet est nécessaire, puisque la nature des requêtes sera toujours identique (demande d'envoi de l'agenda local). D'autres viendrons ensuite pour permettre à l'utilisateur d'importer ses agendas, d'ajouter, de supprimer ou de modifier des tâches de l'agenda local.
    • Bundles à ajouter à l'environnement : org.apache.felix.http.bundle, org.apache.felix.http.jetty

La principale difficulté à laquelle nous nous sommes heurtés étant que l'activation de la servlet nécessite d'accéder au contexte du Bundle correspondant, ce dont nous ne nous préoccupons habituellement pas avec iPOJO.

Vendredi 7 Juin :
  • Récupération des agendas Google :

Nous nous nous heurtons à des problèmes...

  • Serveur Web :

Nous avons ajouté au serveur une servlet destinée à l'ajout d'une tâche à l'agenda local. Celle-ci envoie à l'utilisateur un formulaire dans lequel il peut entrer les paramètres de l’événement qu'il souhaite ajouter. Cet ajout a occasionné la création d'un dossier WebContent à la racine du projet, contenant le fichier "create.html" qui définit le formulaire. Il est à noté que nous n'avons pas réussi à utilisé la methode "getDispatcher()" pour envoyer la page html et nous avons contourné ce problème en lisant le fichier "create.html" et en stockant tout son contenu dans un String qui est ensuite envoyé à l'utilisateur par la servlet.
En raison de ce problème nous ne pourrons pas faire de JSP, et par conséquent la génération d'une partie de notre futur code HTML devra sans doute être fait depuis le code Java lui-même.

Samedi 8 Juin :
  • Récupération du Google Agenda :

La récupération d'un agenda Google est enfin possible... Finalement nous n'utilisons ni l'API Google, ni la méthode REST. Nous avons été découragés par le peu de documentation sur l'API et par la complexité de la méthode d'authentification employée par Google.
Nous utilisons la méthode load fournie par la librairie ical4j qui permet de récupérer un agenda à partir de son URL. L'utilisateur doit juste indiquer l'URL de son agenda, accessible en 3 clicks alors que trouver les informations nécessaires à l'authentification imposée par l'API relève du parcours du combattant. Il a donc le choix des agendas qu'il rendra disponible, s'il le veut il pourra fournir uniquement une URL public et les évènements privés de son agenda ne seront donc pas récupérés et pas affichés.

  • Il est désormais possible d'ajouter un objet 'event' dans un agenda à l'aide de la méthode : public void createComponent(java.util.Calendar start, java.util.Calendar end, String eventName). Les paramètres de cette méthode sont les dates de début et de fin ainsi que le nom de l'événement.

Un component est l'objet Java qui représente un événement ou encore une tâche.

Lundi 10 Juin :
  • Affichage des agendas :

La liaison entre le serveur web et le dispositif d'affichage fonctionne, nous sommes à même d'afficher le contenu d'une page HTML générer par le composant WebServer sur la liseuse. Nous nous lançons donc la génération de la page affichant les agendas des utilisateurs et l'agenda commun. La première étape étant la mise en place de la structure d'échange de services.
Votre agenda.png

  • Implémentation de la méthode public void removeComponent(net.fortuna.ical4j.model.property.Uid uid) qui supprime un Component dans un agenda à partir de l'uid passé en paramètre.

Note : l'Uid est un objet qui permet d'identifier un component de manière unique.
Cette méthode est appelée directement par la servlet dans la méthode doPost. L'uid du "component" à supprimer est passé en paramètre de la requête HTTP grâce à une balise de type "hidden" dans le formulaire HTML de la page de suppression de tâches.
La modification d'un "component" consistera pour l'instant en une suppression suivit d'une redirection de l'utilisateur vers la page de création d'une nouvelle tâche.

Mardi 11 Juin :
  • Web Server :

Au vues de l'importance des traitements qui doivent être effectués sur les requêtes HTTP pour l'interface utilisateur, Nous avons créé dans le package WebServer de nouvelles classes. Ces objets utilitaires sont instanciés et utilisés par les servlets associées aux différentes actions proposées par l'interface. Cette organisation permet d'alléger considérablement le code de la classe WebServerImpl (sachant que les servlets ont été implémentées sous la forme de classes internes à WebServerImpl). En effet l'utilisation de la fonction "printWrite()" à la place de "getRequestDispatcher()" nous oblige à générer les pages html (du moins les parties dynamiques) intégralement dans le code java.

Mercredi 12 Juin :
  • Affichage des agendas :

L'affichage des agendas sur la Kindle est maintenant géré.
Nous avons fait le choix d'afficher les agendas en format portrait, côte à côte afin de bien distinguer les tâches de chacun (la Kindle étant en niveau de gris, dur d'utiliser un jeu de couleurs). Pour rendre l'affichage le plus lisible possible nous avons séparé la journée en 3 tranches : 00h - 08h ; 08h - 16h ; 16h - 00h. C'est le découpage qui nous semblait le plus cohérent car il correspond à des phases "caractéristiques" de la journée. Dans cet affichage nous considérons les événements par tranches horaires de une heure uniquement. La taille réduite du Kindle nous imposait cette contraire, nous aurions autrement trop perdu en clarté. En accord avec nos tuteurs nous avons décidé que les tâches destinées à commander les appareils électroniques via le protocole UPnP (préfixées par "CMD") n'apparaîtraient pas sur la Kindle.
A cause de la difficulté de faire des servlets en JSP, nous avons opté pour une méthode un peu moins conventionnelle : générer du code HTML directement depuis notre code Java. Nous avons donc créé une classe "PrintWrite" qui contient la méthode PrintWriteHtml. Cette méthode prend en paramètre les agendas à afficher, constitués uniquement d'événements appartenant à l'intervalle de temps et ayant été triés au préalable par ordre de date croissant, ainsi que la date de début du créneau d'affichage. Nous utilisons un buffer pour stocker les chaînes de caractères à écrire du le fichier HTML intitulé "print.html" et situé dans le répertoire "WebContent/WEB-INF". Dans un premier temps nous écrivons l'en-tête HTML, c'est à dire les metadatas et le CSS, ensuite le "body". Nous avons choisi d'utiliser une "table" (tableau en HTML) pour représenter les calendriers, cela permet de bien séparer les différents agendas, les différentes plages horaires et les événements au sein même de la table. Depuis notre code Java, à l'aide d'une boucle représentant nos différents créneau horaire et d'un itérateur sur nos calendriers, nous testions si l'événement courant correspondaient au créneau sur lequel on se trouvait, si oui nous ajoutons une ligne à la table avec comme classe "event" et comme rowspan (nombre de ligne occupées par la case) le nombre d'heures de la tâche et ayant comme valeur le nom de l'event (champ SUMMARY du composant); sinon nous écrivons une ligne de classe "noEvent" avec un rowspan de 1 et sans valeur. Les différentes classes permettent de déterminer la couleur de la casse et la présence ou non de lignes séparatrices. Comme les événements des agendas ont été triées dans l'ordre de durée croissante, pas de risque de laisser une tâche en route. Ce traitement tient compte d'événements non seulement strictement contenu dans l'intervalle de temps, mais aussi les événements "débordant" par le bas et/ou le haut. Une fois les agendas parcourus entièrement et les lignes écrites, nous fermions le flux de fichier et le buffer.

  • Gestion des urls :

Il est désormais possible d'entrer manuellement (grâce à l'interface web) les urls des agendas google qui devront être récupérés par l'application.
Nous avons décidé de limiter pour l'instant à deux le nombre maximal d'agendas google synchronisés afin de ne pas surcharger l'affichage sur la kindle. Les urls de ces agendas peuvent être rentrées par les utilisateurs au moment de leur inscription. Toutefois, cette option ne leurs est proposée que pour les deux premières inscriptions, après quoi il ne sera plus possible d'ajouter une url à son compte.
L'ensemble des utilisateurs inscrit est stocké sous la forme d'une liste d'objets de type "Users" contenant le nom, l'email et éventuellement l'url de l'agenda google de l'utilisateur. Cette liste d'utilisateurs constitue un attribut du module "LocalAgenda" de l'application.

Jeudi 13 Juin :

L'une des raisons pour lesquelles notre dispositif peut être qualifié d'intelligent est qu'il communique avec son environnement et notamment avec les usagers. Pour permettre au système de communiquer avec les usagers, où qu'ils soient, nous avons décidé pour des raisons de simplicité et de délai de recourir aux mails. Bien qu'il serait préférable qu'à terme l'utilisateur soit prévenu par SMS.

  • Envoi de mail :

Deux des services à implémenter ont recours à l'envoi d'un mail pour prévenir l'utilisateur : le rappel d’événement et la détection de conflit. Pour ce faire, nous avons récupéré un bundle qui fournit l'API javax.mail en version 1.5.0-b01. Lien de téléchargement du bundle http://mvnrepository.com/artifact/javax.mail/mail/1.5.0-b01 La dépendence à ajouter au pom associé est la suivante :

<dependency>
 <groupId>javax.mail</groupId>
 <artifactId>mail</artifactId>
 <version>1.5.0-b01</version>
</dependency>

Procédé d'envoi d'une alerte et utilisation de threads : Les alertes sont programmées par l'utilisateur pour être envoyées à un moment précis avant le début de l'événement. Le procédé que nous avons retenus pour envoyer ces alertes est le suivant. On fait appel à une méthode qui vérifie s'il est nécessaire d'envoyer une alerte à intervalle de temps réguliers. A chaque appel, cette méthode récupère toutes les alarmes dont l'envoi est prévu entre la date courante et le prochain appel de la méthode. A chaque alarme on associe un thread qui va s'endormir pour une durée égale à la date de l'envoi de l'alarme à laquelle on soustrait la date courante. A son reveil le thread envoie le mail à la (aux) personne(s) concernée(s). L'inconvénient de cette méthode est qu'on ne vérifie pas si au reveil du thread l'utilisateur a supprimé l'événement. La probabilité d'apparition de ce cas de figure diminue avec le délai entre chaque appel à la méthode. Pour une implémentation rigoureuse il conviendra de vérifier la présence de la tâche juste avant l'envoi du mail.

Vendredi 14 Juin :
  • Affichage des agendas :

Dorénavant des tâches se superposant n'engendrent plus d'erreurs sur l'affichage. C'est la tâche de durée la plus longue qui est afficher en priorité, puis si la durée est la même c'est la tâche commençant le plus tôt qui est affiché, et enfin si les tâches commencent en même temps c'est l'événement ajouter en dernière qui est affichée. De plus l'affichage est maintenant diviser en demi-heure afin que l'affichage soit plus fin. Finalement l'affichage reste lisible et permet à l'utilisateur d'éviter des heures de lecture. Nous envisageons d'afficher un signal d'alerte du type /!\ pour marquer un conflit entre plusieurs événements.


Dimanche 16 Juin:

Notre projet touche bientôt à sa fin...demain nous avons notre soutenance final. C'est donc le bon moment pour faire un petit bilan sur notre travail et d'en profiter pour énoncer les améliorations qui pourraient être selon nous intéressant d’implémenter que nous avons pas pu par manque de temps mettre en place mais qui serait dans la continuité de notre travail.

En ce qui concerne les points positifs: la majeur partie des objectifs que nous nous étions fixés avec nos tuteurs ont été atteint.

  • L'affichage sur notre liseuse est réalisé et permet en effet à une famille de visualiser les différents agenda de ses membres et ainsi facilite l'organisation de la famille.
  • Ensuite en ce qui concerne l'agenda la création d'un agenda qui serait commun à toute la famille et indépendant des agendas google synchronisés, c'est fait il est possible pour les utilisateurs d'ajouter, de supprimer, de modifier des événements depuis l'interface web.
  • La gestion des alarmes et des rappels est faite chaque utilisateur est prévenu par mail d'un événement le concernant (à condition que l'option rappel est été indiquée à sa création) au moment précis de l'alarme.
  • La partie la plus importante de notre module brain concernait la gestion des conflits afin de ne pas assigner une même personne à 2 tâches en même temps.
    Nous faisons la vérification à chaque fois,que l'événement soit créé dans l'agenda local ou bien dans un agenda google. En cas de conflit un mail est envoyé à la personne concernée et sur notre afficheur permanent nous montrons qu'il y a un problème via la balise " /!\ "
  • La différenciation entre des événements et des tâches qui devront être ensuite exécutées par les équipements électroniques de la maison à l'heure précise du début de la tâche.


A propos de cette dernière fonctionnalité il y a de nombreuses pistes d'amélioration qui peuvent en découler afin de permettre la communication avec les appareils électroniques de la maison. En effet pour le moment nous ne faisons qu'envoyer un mail à l'heure indiquée lorsqu'un événement est préfixé par "CMD" et la continuation serait d'utiliser le protocole UPnP afin d'offrir plus de services au client.