samedi 17 décembre 2011

Domotique - Température: Thermostat on the www, Google Calendar est mon ami

Suite à la mise en oeuvre du DS18B20, je m'étais fait une petite page web (en complément de celle présentant les courbes) permettant de régler la température désirée, ainsi que le capteur sur lequel étaient réalisés les contrôles.
Le côté pratique de cette page est vite apparu: il était possible de modifier la température de n'importe où dans le monde, que ce soit à la maison ou ailleurs, du moment qu'un accès web était présent.

D'un autre côté, il n'était pas possible de programmer la température désirée sur le long terme, et transformer ladite page web pour en faire un point d'entrée de thermostat d'ambiance me freinait à plusieurs niveaux:

  • faire une IHM au format html (ou autre) permettant de facilement programmer plusieurs plages de températures sur plusieurs jours (et sans se limiter, comme sur certains thermostats, à 2 niveau de chauffe possibles et des plages découpées à la demi-heure) est mission impossible ou presque (et je n'ai pas que ça à faire)
  • il fallait ensuite envoyer l'info à mon serveur à la maison pour que ça finisse d'une manière ou d'une autre dans mon Arduino
  • il fallait enfin modifier le sketch de l'Arduino afin que lui aussi gère toutes ces données, et cette mission me paraissait aussi plaisante que celle du premier point
J'ai donc cherché sur le web des solutions clés en main, sachant que l'aspect graphique devait être pré-maché au maximum: j'ai réalisé cette installation pour l'aspect Arduino, pas pour passer des heures à faire des pages web.
Je suis donc rapidement tombé sur le seul candidat potentiel: le calendrier de Google, d'autant que j'ai vite vu que Python est l'ami de Google, et que des librairies de mise en oeuvre sont existantes.
Google Calendar permet de s'affranchir de tout l'aspect graphique, est utilisable partout car il n'y a pas de client à installer, et marche même dans l'univers Android. On peut donc même faire chauffer la maison quand on est dans le train, histoire qu'il fasse bon quand on arrive à la maison !

Pré-requis
Pour pouvoir mettre en oeuvre cette interface entre Google Calendar et Arduino, il faut:

  • Un accès Gmail
  • L'id du calendrier
  • un PC faisant l'interface entre Arduino et le www, hébergeant un script python qui va récupérer les données dans Google Calendat
Accéder à Google Calendar
Sous Google Calendar, afin de ne pas trop polluer mon planning utilisé pour la vie courante, j'ai créé un nouvel agenda en cliquant sur la liste déroulante située à coté de Mes agendas

Il faut ensuite récupérer l'ID de cet agenda, il nous sera utile pour y accéder depuis le code Python.
Cliquer sur la liste déroulante située à côté de l'agenda créé (Thermostat dans mon cas), puis sur Propriétés
L'ID de l'agenda est visible au niveau de l'URL.
Attention à ne pas récupérer l'adresse dispo au niveau de la zone d'insertion du planning: ça risque de ne pas fonctionner


Thermostat d'ambiance
L'avantage indéniable de l'utilisation d'un agenda est de pouvoir définir des plages de chauffe précises, répétables facilement, et dans lesquelles il est possible de définir une température précise.
Mon choix s'est porté sur la synthaxe suivante:
Th_nom-sonde:température-désirée

En complément, j'ai défini une synthaxe simplifiée:
Th_nom-sonde, ou même Th_
Dans ce cas, la température appliquée est une température définie en configuration (par l'intermédiaire d'une page web).

Afin de ne pas avoir à tapisser tout le planning de plaquettes, une absence de plaquette entraîne l'application  automatique d'une autre température de consigne, telle que la température hors gel qu'on trouve sur les thermostats habituels


Il est donc toujours possible d'utiliser le thermostat à minima:
  • pas de plaquette = température hors gel
  • plaquette sans consigne = température de consigne

Google Calendar est interrogé toutes les 5mn. Par l'intermédiaire d'une séquence spécifique, il est possible de forcer une interrogation immédiate de l'agenda


Paramètres par défaut
En complément des 2 températures une valeur de delta (écart de température à atteindre pendant le cycle de chauffe avant l'arrêt du chauffage) est définie, ainsi qu'un capteur de température.
Ces paramètres sont modifiables par l'intermédiaire d'une page web sécurisée, et récupérés toutes les 10mn par le script Python.
Par l'intermédiaire d'une séquence spécifique, il est possible de forcer une prise en compte immédiate de ces valeurs

Zoom sur les échanges de données
Ci-dessous, un résumé (un peu succinct) des échanges entre les modules principaux: web, PC, Arduino:

Récupérer les données de Google Calendar
Le code Python permettant de récupérer les données de Calendar est simple. Il récupère la liste des évènements de la journée, puis contrôle si des évènements sont actifs au temps courant.
Si un évènement est actif, le titre de la tâche est récupéré puis traitée pour être transmise à l'Arduino

Connexion à Google Calendar sur la plage désirée (la journée courante):

import gdata.calendar.service
import gdata.calendar
import datetime

cal_client = gdata.calendar.service.CalendarService()
cal_client.email = "VOTRE_LOGIN"
cal_client.password = "VOTRE_PASSWORD"
cal_client.source = 'Google-Calendar_Python_Sample-1.0'
cal_client.ProgrammaticLogin()

query = gdata.calendar.service.CalendarEventQuery('ID_CALENDAR@group.calendar.google.com', 'private', 'full')
auj=str(datetime.date.today())
query.start_min = auj
dem=str(datetime.date.today()+datetime.timedelta(1))
query.start_max = dem
feed = cal_client.CalendarQuery(query)

Contrôle des heures début/fin des consignes:

for event in feed.entry:
    for a_when in event.when:
        str_date_deb=a_when.start_time
        # Passage du format str au format datetime, pour pouvoir contrôler ensuite les heures de début/fin avec l'heure courante:
        date_deb = datetime.datetime(int(str_date_deb[0:4]) , int(str_date_deb[5:7]), int(str_date_deb[8:10]), int(str_date_deb[11:13]), int(str_date_deb[14:16]), int(str_date_deb[17:19]), int(str_date_deb[20:22]))
        str_date_deb=a_when.end_time
        date_fin = datetime.datetime(int(str_date_deb[0:4]) , int(str_date_deb[5:7]), int(str_date_deb[8:10]), int(str_date_deb[11:13]), int(str_date_deb[14:16]), int(str_date_deb[17:19]), int(str_date_deb[20:22]))
   
        if ((date_deb<=datetime.datetime.now()) and (date_fin>=datetime.datetime.now())):
              print "Cons.:",event.title.text  
              print "Debut:",date_deb
              print "Fin:",date_fin

Voilà !
Vous avez normalement tous les outils vous permettant de lire le contenu de Google Calendar. Google permet aussi bien d'autres actions, comme créer de nouvelles entrées par exemple.



PS: Merci à Code 18 pour cette modif permettant d'insérer du code proprement dans blogspot !