Ou comment connecter entre eux objets (capteurs et actioneurs) et bases de données... Voici un petit post pour présenter gsensors, une petite bibliothèque de glue en Python à base de gevent pour brancher entre eux capteurs, actioneurs et bases de données.
Attention: tout cela est "en construction", l'idée est juste de partager mon experience de bidouillage (du dimanche) avec de "l'internet des objets". Peut-être cette bibliothèque peut vous être utile aussi, mais dans tous les casce n'est pas une solution magique et clés-en-main...
Bref, je commence à mettre des capteurs dans ma maison : temperature/humidité, consomation électrique, etc. Je tatonnne aussi sur quelques "actionneurs". Pour le moment en plus d'un CurrentCost, de quelques multiprises mPower, j'ai recyclé une libellule (voir photo) avec un ESP8266 : elle gère un bouton pousoir, mesure la temperature et peut s'allumer ou s'etteindre, le tout en MQTT par wifi (post à venir la dessus).
Pour "brancher" entre eux tout ces objets et socker les données, je ne me voyais pas utiliser une "grosse" solution existante clé en main (type domoticz ou mFi®Controller). D'une part le hardware que j'utilise est vraiment hétérogène (je fait avec ce que j'ai...), et ensuite j'ai vraiment envie d'expérimenter plein de choses simples qui ne le restent pas forcément quant on doit s'intégrer à un soft qui n'a pas été prévu tout à fait pour ca... Je préfaire m'appuyer sur différents logiciels (influxDB, grafana, MQTT, etc.) et gérer "la glue" directement à la main avec un petit lot de scripts Python qui font chacun une tache précise. J'ai commencer gsensors pour avoir une bibliothèque qui simplifie (et factorise) la rédation de ces scripts.
Pour donnée une idée, j'ai pour le moment trois scripts : l'un surveille un bouton (topic MQTT) et en fonction active ou desactive une prise sur un mPower (des lampes sont brancher dessus), un autre récupère des données externes (météo et niveau d'eau de la rivère pas loin de chez moi) et le dernier enregistre dans une base InfluxDB les valeurs de consomation electrique de la maison.
Plutot qu'un grand discours, pour donnée une idée, voici un exemple de script qui récupère (toutes les 15 minutes) la hauteur d'eau de l'albarine à Saint-Denis-en-Bugey (la page de la station sur vigicrues est ici :
#-*- coding:utf-8 -*-
import sys
from influxdb import InfluxDBClient
from gsensors import GSensorApp
from gsensors.vigicrues import VigicruesSource
from gsensors.databases import InfluxDBPublish
def main():
app = GSensorApp()
station_id = 810 # identifiant sur vigicrues
vgs = VigicruesSource(station_id=station_id)
# Influxdb
## Attention a changer les identifiants de connection
idb_client = InfluxDBClient("localhost", "8086", username="toto", password="tata", database="river")
tags = {
"station_id": "%s" % station_id,
"station_name": "St-Denis-En-Bugey",
}
vgs.on_change(InfluxDBPublish(idb_client, measurement="h_eau", tags=tags))
app.add(vgs)
app.run()
if __name__ == '__main__':
sys.exit(main())
En deux mots gsensors propose des DataSource
sur les quelles il est possible de brancher des actions (on_change
)... rien de plus.
Pour le moment, j'ai codé des sources pour :
- MFI-MPower : multiprises connecté (Wifi) de Ubquiti,
- API OpenWhetherMap : infos météo externe,
- Vigicrues (scraping) : niveau d'eau des principales rivières en France,
- CurrentCost : consomation électrique et température transmis par la liaison série du EnviR
- MQTT : enregistrement sur un topic MQTT...
Il y a aussi des bouts de code pour publier dans un base influxDB (0.9) ou sur un topic MQTT.
Dans les choses à faire pour la suite... en gros pour le moment c'est une petite lib bidouillage du dimanche, si c'est utile à d'autre, il y a un travail "d'industrialisation" à faire (doc et tests surtout).
Sinon coté fonctionalitées, je me note dans ma TODO liste :
- clarifier les evénéments sur les
DataSource
(on_error, on_update, ??), - ajouter des actions type envoie de mail, de sms, etc. En particulier en cas d'erreur sur une
DataSource
, - documenter, et packager mieux la lib,
- tests automatiques et unitaires (a priori avec py.test)...