Affichage des articles dont le libellé est Google Script. Afficher tous les articles
Affichage des articles dont le libellé est Google Script. Afficher tous les articles

Domotique: Profiter des services Google ...

Utiliser Google Script pour s'interfacer avec le web
J'ai depuis un (trop) long moment de sérieux problèmes avec Google Calendar: il n'est pas rare (ça arrive au moins une fois par jour) qu'un RDV déclaré dans Google Calendar ne soit pas récupéré par l'API Python. je suis obligé de modifier ce RDV pour qu'il soit de nouveau détecté. Même problème si je supprime un RDV: celui-ci est toujours rapatrié par l'API Python, ce qui est gênant car il n'y a alors aucune solution pour rectifier le tir ...

J'ai décidé de prendre le problème à bras le corps: supprimer cette partie un peu faiblarde de mon installation pour la remplacer par une solution que je pense plus pérène à plusieurs égards, en profitant des services Google pour:
- récupérer les infos depuis Calendar,
- les mettre en forme, près à être traités par mon script Python,
- effectuer la remontée vers le site web pour suivre les évolutions de mon chauffage (j'ai aussi traité mon alarme, mais je préfère ne pas trop échanger à ce propos ...)

La solution est d'utiliser Google Script, pour récupérer les infos de Google Calendar, les stocker dans un tableur de Google Drive, que je viens lire avec un script Python. Résultat: une bonne partie de la charge de travail (lecture de Google Calendar pour les consignes de chauffage et de l'alarme) sont désormais dédiés à Google, plus à mon installation.
De même, je gérais autrefois l'historisation des courbes de températures et la génération de la page web. C'est désormais Google qui gère tout ça, au travers de l'exploitation directe des graphiques du tableur dans une page web de Google Sites.

L'idée derrière tout ceci est que je compte très prochainement modifier toute mon installation afin de la rendre 100% autonome, en rajoutant une carte Ethernet à mon Arduino. L'exploitation des données de Google se fera directement depuis le sketch de l'Arduino. Exit le PC qui tourne sous Python !

Logique des échanges
Le but de ce passage sous Google Script est de:

  • Lire cycliquement les données de Google Calendar de la journée courante, puis les copier dans un tableur Google. Google Script permettant de le faire toutes les minutes, je ne me suis pas privé: ça rend les prises en comptes plus rapides lors de changements, et la charge est chez Google ...
  • Depuis le script Python, lire cycliquement le contenu de ce tableur Google. Je n'ai pas changé le taux qui j'avais dans mon ancienne version (de l'ordre de 5mn)
  • Depuis le script Python, envoyer cycliquement les températures des sondes, l'état de commande de chauffage (en route ou pas), la valeur de la température de consigne. Dans l'ancienne version, ces lectures étaient stockées toutes les 5mn, et envoyées vers le site web toutes les demi-heures, ce qui faisait que ce n'était guère exploitable sur le coup. Désormais, j'envoie ces données dans un autre tableur Google toutes les 3mn
  • Générer les indicateurs (températures courantes) et les historiques. Les indicateurs et les courbes que l'on peut générer dans le tableur Google sont directement exploitables dans des pages web d'un Google site. Les historiques sont établis par Google script à partir des données sauvegardées toutes les 3 minutes: le script me fait des moyennes des mesures toutes les 15mn pour m'afficher un historique sur 4 heures, et des moyennes toutes les heures pour un historique à 48h
Le résultat...
Rendez-vous sur le site pour voir ce que ça donne !

Les scripts
Concernant Google Script, vous trouverez une approche dans ce post.
Côté Python, c'est ici qu'il faut aller voir ... un post arrive prochainement

Domotique: Echanger des SMS avec son Arduino

Mon Arduino m'envoie des SMS (et je le lui rends bien ...)
J'ai récemment complété mon installation domotique existante (une commande de chauffage décrite dans ce blog, ainsi qu'un système d'alarme ... pas décrit ...) avec un système de commandes (et de retours de la part de mon installation) par SMS interposés.
Plutôt que d'investir dans un shield officiel (qui tourne autour de 50 euros, ce que je trouve hors de prix), j'ai préféré la réutilisation d'un ancien téléphone portable qui trainait dans un de mes tiroirs: un Sagem MyX4.
Avantage: ce téléphone a encore un port série, et se branchait sur un port DB9 de PC.
En interfaçant mon Arduino sur le câble série d'origine, moyennant le passage par un adaptateur MAX232 acheté sur e-bay, il est très simple de communiquer avec lui.

Certains téléphones GSM sont en effet équipés d'un modem, et acceptent les commandes AT.
Le protocole AT permet, au moyen d'une simple ligne de commande, d'envoyer ou lire un SMS.

Compatibilité AT
Tous les téléphones GSM n'étant pas équipés d'un modem, un petit test préliminaire (depuis un PC) s'impose.
Tout d'abord, il faut relier le téléphone à un port série du PC, puis configurer (si possible, ce qui est normalement le cas des anciens téléphones se branchant sur port série) la vitesse du port série. Le MyX4 permet par exemple de faire des échanges à une vitesse maxi de 38400bd.
Lancer ensuite un hyper terminal sous Windows, en choisissant la configuration suivante:

Dans le terminal, saisir ensuite (attention, il va falloir suivre, c'est complexe !):
AT puis appuyer sur Entrée

Si le téléphone est compatible, il va répondre:
OK

Vous pouvez prendre une pause bien méritée ...

Format des SMS
Saisir ensuite AT+CMGF?
Si le téléphone répond 1, c'est gagné, vous pourrez envoyer des SMS au format texte. Attention cependant, le format texte implique des envois avec du texte simple sans caractères accentués.
Si le téléphone répond 0:
Saisir AT+CMGF=1 pour tenter de forcer le mode texte.
Si le téléphone répond ERROR, votre tel n'acceptera d'envoyer / recevoir des SMS qu'au format PDU. Allez donc faire un petit tour sur cette page ...

Envoyer un SMS
Tapez AT+CMGS="num_tel_cible" puis Entrée
Un prompt > s'affiche
Tapez le contenu du SMS, puis CTRL-Z pour envoyer
Le téléphone va vous répondre quelque chose du genre: +CMGS:01

Après quelques secondes, votre destinataire va recevoir votre SMS

Recevoir un SMS
Il va falloir déterminer où sont stockés vos SMS reçus. C'est normalement configurable dans le téléphone, mais une commande AT va vous permettre de vous aider. Les SMS peuvent être soit stockés dans la mémoire du téléphone (ME), soit sur la sim (SM).
Si vous lisez à un endroit où il n'y a pas de SMS, le téléphone ne vous répondra rien lors de vos demandes de lecture.
Choisissez tout d'abord la zone de stockage. Par exemple, pour lire la mémoire du téléphone, tapez:
AT+CPMS="ME"

Pour lire les SMS, tapez ensuite AT+CGML="ALL"
Si un/des SMS se trouvent dans la zone choisie, vous aurez droit à une réponse du genre:
+CGML:900,"REC UNREAD",+336xxxxxxxx",,12/02/13,19/99/99+02"
CONTENU DU SMS

Effacer les SMS
Pour supprimer un SMS, il suffit (normalement) de saisir:
AT+CGMD=Indice_du_SMS
Il se trouve que cette commande ne fonctionne pas sur mon tel. Par contre la commande suivante fonctionne sans problème:
AT+CGMD=1,4
J'ai trouvé cette astuce je ne sais plus trop où. En gros elle doit supprimer tous les SMS reçus, ou au moins les 4 premiers. Toujours est-il que cette commande fonctionne.

Via Arduino
L'envoi ou la réception depuis l'Arduino est somme toute très simple: il suffit de fixer la vitesse du port série à la même vitesse que celui du téléphone, puis de communiquer via Serial.print ou Serial.read.
Pour ma part les commandes implémentées sont assez simples: Th20 pour fixer le chauffage à 20°, ou ThOff pour l'éteindre. Même chose pour l'alarme: AlaOn ou AlaOff.

Mon installation domotique me répond à toute mes commandes pour m'indique si elle a bien pris en compte. De même, je suis prévenu si l'alarme se déclenche ...

Sans trop investir, il est donc possible de s'ouvrir pas mal de possibilités. Et merci à Free, qui permet de faire tout ça pour 2€ par mois !



Une solution alternative, 2 euros moins cher !

Moyennant quelques restrictions, vous n'aurez besoin ni d'abonnement Free, ni même de modem !

Il y a quand même 4 (plus ou moins grosses) limites:
- seul votre Arduino pourra vous sms-er
- il faudra éviter les surconsommation sous peines de blocages (temporaires), mais cette limitation est contournable si vous avez les data actives sur votre téléphone (pour recevoir les notifications de l'agenda Google)
- seul le titulaire de l'agenda Google sera prévenu
- il faut que votre Arduino puisse communiquer avec un PC (via la liaison série par exemple)


Il suffit pour cela de détourner un peu l'utilisation de base de Google Calendar.

A chaque fois que vous créez une tâche dans l'agenda Google, il est possible de paramétrer cette tâche afin d'être prévenu par SMS, alerte ou e-mail.
Il suffit donc de faire un petit script pour qu'il crée une tâche avec demande de SMS et/ou de notification, et vous recevrez ce SMS et cette notif après quelques secondes. Après essais d'une 20aine de tâches (sur une courte période, il s'avère que les SMS ne passent plus (Google doit faire un blocage) mais ça revient très vite, et ça ne coupe même jamais si on n'abuse pas.
Dans tous les cas, les notifications, elles passent toujours (mais il faut garder les data actives sur le téléphone récepteur)

Côté Arduino
En partant du principe que votre Installation Arduino détecte l'évènement à notifier par SMS, et que le PC fait le traitement de création de tâche, autant dire que la notification Arduino->PC est plutôt simple: un simple Serial.Println d'une chaine de caractères quelconque fera l'affaire.

Côté PC
Google fournit une API permettant de créer des évènements (ou de les lire, comme dans mon installation de commande de chauffage) avec Calendar.
Pour ma part j'ai choisi de m'interfacer avec Calendar via des scripts Python.

Voici donc le script permettant de créer ces évènements:


try:
    from xml.etree import ElementTree
except ImportError:
    from elementtree import ElementTree
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import atom
import base64
import time

def send_sms(message_text):
    cal_client = gdata.calendar.service.CalendarService()
    cal_client.email = "identifiant GMAIL"
    cal_client.password = "mot de passe GMAIL"
    cal_client.source = 'calendar-sms-misuse-1.0'
    cal_client.ProgrammaticLogin()

    event = gdata.calendar.CalendarEventEntry()
    event.title = atom.Title(text=message_text)
    event.content = atom.Content(text="")

    
    # Les notifs par SMS ne fonctionnent pas si elles ne sont pas programmées pour être déclenchées
    #  au moins 5mn avant le début de la tâche
    # On crée donc une tache commencant dans 6mn, d'une durée de 1mn
    start_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime(time.time()+(6*60)))
    end_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime(time.time() + 7*60))
    when = gdata.calendar.When(start_time=start_time, end_time=end_time)
    # On crée une alerte à 5mn:

    # Dans le cas où on veut être alerté par tous les moyens possibles
        reminder = gdata.calendar.Reminder(minutes=5, extension_attributes={"method":"all"})
    # Dans le cas où une notif suffit
        reminder = gdata.calendar.Reminder(minutes=5, extension_attributes={"method":"alert"})
    # et dans le cas d'un SMS
        reminder = gdata.calendar.Reminder(minutes=5, extension_attributes={"method":"alert"})
        
    when.reminder.append(reminder)
    event.when.append(when)

    cal_client.InsertEvent(event, '/calendar/feeds/default/private/full')



send_sms("contenu du SMS")
En espérant que ces 2 méthodes vous soient utiles !

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 !