Plan (hide)
- 1. MQTT
- 1.1 Mosquitto
- 1.2 MQTT pour arduino et ESP8266
- 1.3 Programmation
- 2. OpenHAB
- 3. Pour aller plus loin
- 4. Sources
Une fois que l'on a commencé à jouer avec un arduino, un ESP8266, un raspberry, des capteurs cela donne envie de continuer un peu plus loin au pays de la domotique. C'est à ce petit voyage que je vous convie en suivant mes premiers pas avec OpenHAB, MQTT, ESP8266, mosquitto ... and Caux !
1. MQTT
MQTT (MQ Telemetry Transport) permet la communication entre et avec des « objets connectés ». C'est un protocole pour les réseaux sans fil et à faible bande passante. Il repose sur un fonctionnement de type publication/abonnement hautement évolutif qui garantit la distribution. Il y a donc des publieurs (les publishers) qui envoient des données sur un canal (une chaîne d’information) appelé Topic. Ces données peuvent être lus par les souscripteurs (les subscribers) qui surveillent certains Topics. Un serveur (Broker) se charge de faire la liaison entre les publieurs et les souscripteurs. Les messages envoyés par les objets communications peuvent être de toute sortes mais ne peuvent excéder une taille de 256 Mo.
Le protocole a les propriétés suivantes :
- la distribution de type "un à plusieurs" des messages ;
- la fonction de publication/abonnement découple les applications ;
- il ne dépend aucunement du contenu des messages ;
- il fonctionne sur TCP/IP.
- Il propose trois qualités de service pour la distribution des messages :
- "Au plus une fois"
- "Au moins une fois", les messages arrivent de façon certaine, mais ils peuvent arriver en double.
- "Une seule fois"
- Il dispose de la fonction "Dernières volontés et testament" qui notifie les abonnés de la déconnexion anormale d'un client du serveur MQTT.
1.1 Mosquitto
Il existe plusieurs courtiers de message MQTT (broker), mais Mosquitto est un projet opensource que l'on peut installer sur un raspberry pi et utiliser avec un ESP, c'est donc celui-ci qui a notre préférence et que nous allons présenter et installer. La configuration par défaut de Mosquitto n'utilise pas d'authentification et accepte toutes les connexions sur le port 1883. Elle possède deux clients mosquitto_pub
et mosquitto_sub
. Le client mosquitto_pub
est utilisé pour poster de publier des message. Le mosquitto_sub
est utilisé pour s'abonner à un sujet et afficher les messages reçus.
Commençons par installer le courtier, les clients et l'api python (cette dernière n'est pas nécessaire ici). Attention il faut récupérer une version de mosquitto à jour sous peine de problème !
% sudo bash -c 'echo "deb http://ppa.launchpad.net/mosquitto-dev/mosquitto-ppa/ubuntu trusty main" > /etc/apt/sources.list.d/mosquitto-dev-mosquitto-ppa-trusty.list' % sudo apt-get update % sudo apt-get install mosquitto mosquitto-clients python-mosquitto
Le service est normalement actif. Vous pouvez le vérifier :
% ps aux | grep mosquitto mosquit+ 31101 0.0 0.0 14920 2084 ? Ss 09:55 0:00 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf damien 31118 0.0 0.0 15984 2224 pts/0 S+ 09:58 0:00 grep --color=auto mosquitto
Si ce n'est pas le cas
% sudo service mosquitto start mosquitto start/running, process 31142
La commande netstat
vous confirmera que le démon écoute sur le port.
% netstat -an | grep 1883 tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:33805 127.0.0.1:1883 ESTABLISHED tcp 0 0 127.0.0.1:1883 127.0.0.1:33805 ESTABLISHED tcp6 0 0 :::1883 :::* LISTEN unix 2 [ ] STREAM CONNECTE 18830 @/tmp/dbus-RjxvT91U unix 3 [ ] STREAM CONNECTE 18831 /var/run/dbus/system_bus_socket
et si vous voulez l’arrêter
% sudo service mosquitto stop mosquitto stop/waiting
Passons au test maintenant. Le plus simple est d'utiliser deux consoles. Dans la première :
% mosquitto_sub -h localhost -t "DHT22/#" -v &
Vous vous abonnez au canal DHT22
. Dans la seconde
% mosquitto_pub -h localhost -t DHT22/temperature -m 17 % mosquitto_pub -h localhost -t DHT22/temperature -m 17.2 % mosquitto_pub -h localhost -t DHT22/hygrometrie -m 49.8 % mosquitto_pub -h localhost -t DHT11/hygrometrie -m Rien
Dans la première console, on obtient :
DHT22/temperature 17 DHT22/temperature 17.2 DHT22/hygrometrie 49.8
Vous pourrez remarquer que nous n'avons pas le message concernant le capteur DHT11 car nous n'y sommes pas abonné. En guise de test plutôt qu'utiliser localhost
vous pouvez essayer test.mosquito.org
.
1.2 MQTT pour arduino et ESP8266
PubSubClient est un client arduino et ESP MQTT. Il suffit d'installer la bibliothèque dans l'IDE arduino.
1.3 Programmation
Pour commencer en nous inspirant du programme exemple mqtt_esp8266.ino
fourni avec la bibliothèque PubSub
, nous allons écrire un petit exemple qui utilise l'ESP-1 et se connecte sur un broker local lancé sur une machine linux du réseau local. Le traitement consiste à se connecter au Wi-fi (ligne 54 à 74) puis au broker (ligne 100 à 116), ensuite il faut s'abonner à un fil de message serreIN
(ligne 108) et on publie sur un autre fil serreOUT
(lignes 98 et 107). Le fil serreIN
sert à fixer le temps d’endormissement du Wi-Fi pour économiser de l'énergie. Avec un peu de soudure ou un ESP-12 par exemple on peu faire mieux, avec un sommeil plus profond ! Le code est agrémenté de nombreuses traces afin de pouvoir suivre dans la console, pour les supprimer il suffit de commenter #debug
(ligne 16). Pour plus d'informations sur le montage de l'ESP, je vous conseille de vous reporter ce que j'ai expliqué ici.
- /*
- Exemple de base ESP8266 MQTT
- avec une publication de la part de l'ESP qui se connecte sur un broker MQQT (local) :
- - Publie sur le fil "serreOUT" toutes les dodo minutes "[adresse Mac] Bonjour #" + numero_message
- - S'abonne au fil "serreIN" lorsqu'une info est reçue cela fixe la durée d'endormissement du wifi
- pour économiser l'énergie
- source mqtt_esp8266.ino
- */
- #include <ESP8266WiFi.h>
- #include <PubSubClient.h>
- extern "C" {
- #include <user_interface.h>
- }
- #define DEBUG
- #ifdef DEBUG
- #define DEBUG_BEGIN(x) Serial.begin(x)
- #define DEBUG_PRINT(x) Serial.print (x)
- #define DEBUG_PRINTLN(x) Serial.println (x)
- #else
- #define DEBUG_PRINT(x)
- #define DEBUG_PRINTLN(x)
- #endif
- // Pour identifier l'ESP
- uint8_t MAC_array[6];
- char MAC_char[18];
- // Mettre à jour suivant votre réseau
- const char* SSID = "VotreSSID";
- const char* PASSWORD = "VotreMotDePasse";
- byte mqtt_serveur[] = {192, 168, 0, 12}; // IP du broker à modifier
- WiFiClient espClient;
- PubSubClient client(espClient);
- char message[50];
- int numero_message = 0;
- int dodo = 0; // Par défaut
- void setup() {
- DEBUG_BEGIN(115200);
- DEBUG_PRINTLN();
- WiFi.macAddress(MAC_array);
- for (int i = 0; i < sizeof(MAC_array); ++i){
- sprintf(MAC_char,"%s%02x:",MAC_char,MAC_array[i]);
- }
- setup_wifi();
- client.setServer(mqtt_serveur, 1883);
- client.setCallback(callback);
- }
- void setup_wifi() {
- delay(10);
- // Connexion au Wi-fi
- DEBUG_PRINTLN();
- DEBUG_PRINTLN();
- DEBUG_PRINT("Connexion à : ");
- DEBUG_PRINTLN(SSID);
- WiFi.begin(SSID, PASSWORD);
- DEBUG_PRINT("\n\r \n\rC'est en cours");
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- DEBUG_PRINT(".");
- }
- DEBUG_PRINTLN("");
- DEBUG_PRINT("ESP connecté au Wi-fi ");
- DEBUG_PRINTLN(SSID);
- DEBUG_PRINT("Adresse IP : ");
- DEBUG_PRINTLN(WiFi.localIP());
- }
- void callback(char* fil, byte* payload, unsigned int longueur) {
- DEBUG_PRINT("Message arrivé [");
- DEBUG_PRINT(fil);
- DEBUG_PRINT("] ");
- dodo = 0;
- int puissance = 1;
- for (int i = longueur - 1; i >= 0; i--) {
- DEBUG_PRINT((char)payload[longueur - 1 - i]);
- dodo = dodo + ((int)payload[i]-48) * puissance;
- puissance = puissance * 10;
- }
- DEBUG_PRINTLN();
- DEBUG_PRINT("dodo = ");
- DEBUG_PRINTLN(dodo);
- }
- void publication()
- {
- ++numero_message;
- snprintf(message, 75, "[%s] Bonjour #%ld", MAC_char, numero_message);
- DEBUG_PRINT("Message publié: ");
- DEBUG_PRINTLN(message);
- client.publish("serreOUT", message);
- }
- void reconnect() {
- // On tente de se (re)connecter
- while (!client.connected()) {
- DEBUG_PRINTLN("Tentative de connexion MQTT...");
- if (client.connect(MAC_char)) {
- DEBUG_PRINTLN("connecté");
- // Une fois connecté on le fait savoir
- client.publish("serreOUT", "Connecté au MQTT");
- client.subscribe("serreIN",1);
- } else {
- DEBUG_PRINT("echec, rc=");
- DEBUG_PRINTLN(client.state());
- DEBUG_PRINT(" nouvel essai dans 5 secondes");
- delay(5000);
- }
- }
- }
- void loop() {
- if (!client.connected()) {
- reconnect();
- }
- delay(2000);
- client.loop();
- publication();
- if (dodo >= 1)
- {
- DEBUG_PRINT("on couche le wifi "); DEBUG_PRINTLN(1000*60*dodo - 2000);
- wifi_set_sleep_type(LIGHT_SLEEP_T);
- delay(1000*60*dodo - 2000);
- }
- }
Il faut maintenant se pencher sur mosquitto
. On utilise la configuration par défaut sans authentification et certificat pour le moment afin de ne pas multiplier les sources d'erreurs. On ajoute néanmoins le mécanisme de persistance afin de pouvoir avoir des capteurs qui s'endorment. J'ai ajouté un fichier mosquitto.conf dans le repertoire /etc/mosquitto/conf.d
avec les paramètres nécessaires, enfin si j'ai bien compris !
Vous pouvez vous en inspirer. Pour une utilisation plus stable, il faut modifier le répertoire de la base par exemple. Je me suis battu également avec la lecture du fichier de configuration aussi je vous conseille d’arrêter le courtier s'il tourne.
% sudo /etc/init.d/mosquitto stop
et lancer le "votre".
% mosquitto -c /etc/mosquitto/conf.d/mosquitto.conf -d -v
Il ne vous reste plus qu'à vous abonner et publier.
L'abonnement et c'est gratuit :
% mosquitto_sub -h armille -t serreOUT -v
et pour publier
% mosquitto_pub -h localhost -t serreIN -m 10 -r
TODO ! Trace d'exécution
2. OpenHAB
OpenHab est un logiciel opensource en Java de domotique interopérable basé sur un bus d’événement. Lorsque l'un de ces derniers se produit un scénario est alors exécuté.
OpenHAB met à disposition :
- Un moteur d’événements, il faut une machine virtuelle Java ;
- Un portail Web mobile configurable ;
- Une API REST.
- Des plugins pour "tout" matériel (module z-wave, bluetooth ...) ou service sur Internet (Twitter, Dropbox ...) leur permettant de communiquer avec le bus d’événement ;
- Un éditeur de règles permettant de définir des déclenchements d'action ;
- Des applications mobiles iOS et Android pour visualiser et déclencher des événements à distance.
2.1 Installation sous ubuntu 14.04
Ajouter tout d'abord la clef et le dépôt :
sudo apt-get update % wget -qO - 'https://bintray.com /user/downloadSubjectPublicKey?username=openhab' | sudo apt-key add - % echo "deb http://dl.bintray.com/openhab/apt-repo stable main" | sudo tee /etc/apt/sources.list.d/openhab.list % sudo apt-get update
C'est parti, on installe openHAB et quelques addons qui pourront être nécessaires.
% sudo apt-get install openhab-runtime openhab-addon-binding-mqtt openhab-addon-action-mail openhab-addon-binding-bluetooth openhab-addon-binding-serial openhab-addon-binding-weather openhab-addon-binding-ntp openhab-addon-persistence-rrd4j
2.2 Configuration
La première chose à faire est de localiser le fichier openhab_default.cfg
. Un petit locate
ou find
vous aideront.
% cd /etc/openhab/configurations % sudo cp openhab_default.cfg openhab.cfg
Il faut maintenant modifier avec votre éditeur favori openhab.cfg
en ajoutant au niveau de MQTT Transport mqtt:mosquitto.url=tcp://localhost:1883
ou si vous préférez le nom de la machine/ip sur laquelle tourne votre courtier. Relancer ensuite openhab
.
% sudo /etc/init.d/openhab restart
L'étape suivante consiste à creer un fichier d'items. Dans ce dernier vous indiquez quels sont les différents capteurs que vous suivez et comment vous les organisez en groupe. Sur le site github d'openHab vous trouverez des explications plus détaillées et claires. Nous allons créer un groupe principal ElevageDeK
avec un Jardin
et une Serre
.
% sudo nano /etc/openhab/configurations/items/default.items Group ElevageDeK Group Jardin (ElevageDeK) Group Serre "Serre" <greenhouse> (Jardin) Number Temp "Température : [%.2f °C]" <temperature> (Serre) {mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/temperature:state:default]"} Number Humidite "Humidité : [%.2f ]" <bath> (Serre) {mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/humidite:state:default]"}
Number
: le type de la valeur ;Temperature
: nom de l'item ;"Température [%.2f]°C"
: affichage de l'information et définition de son format (flottant 2 chiffres après la virgule) ;<temperature>
: le nom de l’icône ;(Serre)
: groupe auquel l'item appartient ;{mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/humidite:state:default]"}
: comment récupérer la valeur. On demande à OpenHAB d'utiliser "mosquitto" et de lire le filElevageDeK/Jardin/Serre/1/OUT/humidite
.state
défini le type etdefault
la transformation.<
indique que l'on lit le fil.
Pour l'icone greenhouse je l'ai récupérée sur le web et copiée dans
/usr/share/openhab/webapps/images/
On fixe maintenant l'interface utilisateur en créant un fichier sitemap
.
% sudo nano /opt/openhab/configurations/sitemaps/default.sitemap
sitemap default label="ElevageDesK" { Frame { Group item=Jardin icon="garden" } }
Vous pouvez tester maintenant :
% mosquitto_pub -h localhost -t ElevageDeK/Jardin/Serre/1/OUT/humidite -m 97
et dans votre navigateur http://localhost:8080/openhab.app
3. Pour aller plus loin
Je vous propose de maintenant construire une application plus complète où nous n'allons pas nous contenter de simuler un capteur et son contrôle mais réellement le réaliser. Cette application peut être une base de départ pour réaliser un suivi et un contrôle de chez vous.
3.1 Éléments nécessaires
Cette liste n'est pas complète, mais donne les éléments essentiels :
- Le broker mosquitto installé ;
- Le serveur openhab installé ;
- Un montage esp8266 avec un DHT22 opérationnel.
3.2 Objectif
Nous allons donc chercher à récupérer la date à partir d'un serveur ntp
, la température locale extérieure grâce à openWeatherMap et la température et le pourcentage d'humidité dans la serre avec un ESP8266-1 et un capteur DHT22. On doit pouvoir également configurer la durée entre deux acquisitions de la mesure par l'ESP dans la serre avec un "endormissement" de celui-ci afin de limiter la consommation d'énergie. Cette application est largement inspirée de la démo d'openhab.
3.3 Configuration des extensions
On utilise différentes extensions, qu'il faut alors configurer.
Liaison avec un serveur ntp
Vérifiez que vous avez bien le fichier /usr/share/openhab/addons/org.openhab.binding.ntp-1.8.2.jar
(remplacez 1.8.2 par votre noméro de version) sinon installez le. Il faut ensuite modifier le fichier /etc/openhab/configurations/openhab.cfg
en ajoutant le serveur ntp
et le rafraîchissement de l'information.
# refresh interval in milliseconds (optional, defaults to 900000 [15 minutes]) ntp:refresh=60000 # the hostname of the timeserver ntp:hostname=ntp-p1.obspm.fr
Liaison avec le broker mosquitto
Comme pour ntp
assurez vous que vous avez bien le fichier /usr/share/openhab/addons/org.openhab.binding.mqtt-1.8.2.jar
(remplacez 1.8.2 par votre noméro de version) sinon installez le. Il Il faut ensuite modifier le fichier /etc/openhab/configurations/openhab.cfg
en indiquant le nom de la machine et le port sur lequel le broker tourne et écoute.
# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883 mqtt:mosquitto.url=tcp://localhost:1883
Récupération de la météo
Vous commencez à connaître l'histoire, il faut vérifier que vous avez bien le fichier /usr/share/openhab/addons/org.openhab.binding.weather-1.8.2.jar
. (remplacez 1.8.2 par votre noméro de version) sinon installez le. Il Il faut ensuite modifier le fichier /etc/openhab/configurations/openhab.cfg
, mais avant cela commencez par créer un compte sur OpenWeatherMap et demandez pour récupérer une clef qui vous permettra d'utiliser l'Api.
et notez votre clef.
Au niveau d'openhab.cf
weather:apikey.OpenWeatherMap=votreClef weather:location.maison.latitude=votreLatitude weather:location.maison.longitude=votreLongitude weather:location.maison.provider=OpenWeatherMap weather:location.maison.language=en weather:location.maison.updateInterval=10
Si vous voulez d'autres lieux, il suffit d'ajouter d'autres identifiants (maison
) qui permettront de récupérer les informations.
3.4 Configuration des fichiers xx.items
Attention à ne pas avoir des items qui ont les mêmes labels dans plusieurs fichiers cela crée des problèmes sur les charts.
Les fichiers items
contiennent les définitions des variables pour échanger des informations au sein d'openhab ou avec d'autres programmes, systèmes, serveurs, courtiers .... Ils précisent également comment les afficher. Ils sont localisés dans le répertoire /etc/openhab/configurations/items
. Ainsi nous allons pouvoir définir une variable Temperature_exterieure
qui va permettre de stocker l'information issue d'OpenWeatherMap, nous allons également pouvoir préciser que l'affichage se fera sous la forme d'un nombre flottant avec deux décimales après la virgule [%.2f °C]
. Le plus simple est de regarder l'exemple ci-dessous.
Group ElevageDeK Group Jardin (ElevageDeK) Group Serre "Serre" <greenhouse> (Jardin) Group Meteo "Meteo" <sun> (ElevageDeK) Group Reglage (ElevageDeK) Group SerreReglage "Réglage des paramètres pour la serre" <settings> (Reglage) Group Serre_Courbes Group Initialiser Number Serre_Temp "Température serre [%.2f]" <temperature> (Serre, Serre_Courbes) {mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/temperature:state:default]"} Number Serre_Humidite "Humidité : [%.2f ]" <dht11_2> (Serre, Serre_Courbes) {mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/humidite:state:default]"} DateTime Date "Date [%1$tA, %1$td.%1$tm.%1$tY,%1$tH:%1$tM ]" <calendar> { ntp="Europe/Paris:fr_FR" } Group Meteo_Courbes Number Meteo_Temperature "Température [%.2f °C]" <temperature> (Meteo, Meteo_Courbes) {weather="locationId=maison, type=temperature, property=current"} Number Meteo_Humidite "Humidité extérieure [%.1f ]" <dht11_2> (Meteo, Meteo_Courbes) {weather="locationId=maison, type=atmosphere, property=humidity"} Number Meteo_Temp_Max "Maximum aujourd'hui [%.1f °C]" <temperature> (Meteo) {weather="locationId=maison, type=temperature, property=max"} Number Meteo_Temp_Min "Minimum aujourd'hui [%.1f °C]" <temperature> (Meteo) {weather="locationId=oudalle, type=temperature, property=min"} Number Meteo_Courbes_Periode "Durée" DateTime Meteo_LastUpdate "Dernière maj. [%1$ta %1$tR]" (Initialiser) <clock> Number FrequenceAcq "Réglage fréquence [%.0f mn]" <myslider> (SerreReglage, Initialiser) Number FrequenceTrans {mqtt=">[mosquitto:ElevageDeK/Jardin/Serre/1/IN/frequence:state:*:default]"} Switch Endormissement "Envoi consigne"
La syntaxe est la suivante (ce qui est entre crochet est facultatif) :
itemtype itemname ["labeltext"] [<iconname>] [(group1, group2, ...)] [{bindingconfig}]
Vous fournissez le type de l'item (Number
, DateTime
, Switch
, Dimmer
, String
....) puis le nom de l'item et le texte qui sera associé et le format de représentation, puis l'icone le représentant et les groupes auxquels il appartient et pour finir l'appel éventuel à un service extérieur (ntp
, mosquitto
...). Prenons un exemple Number Meteo_Temperature "Température [%.2f °C]" <temperature> (Meteo, Meteo_Courbes) {weather="locationId=maison, type=temperature, property=current"}
. On déclare donc un item Meteo_Temperature
de type Number
qui a pour affichage "Température [%.2f °C]"
, [%.2f °C]
indique comment la valeur de la variable sera affichée. Cette variable appartient à deux groupes d'item qui sont (Meteo, Meteo_Courbes)
. Les Group
servent à associer des items entre-eux que ce soient des variables ou des groupes. Ils se déclarent comme des items. Pour en savoir plus je vous conseille de vous reporter à la documentation.
{weather="locationId=maison, type=temperature, property=current"}
est donc la liaison à un service, ici la météo. On fournit la localisation souhaitée en lien avec le fichier openhab.cfg
ainsi que le type. La documentation d'openHab détaille cela. Dans l'exemple ci-dessus vous trouverez également une liaison avec un serveur de temps ntp : { ntp="Europe/Paris:fr_FR" }
.
Je vous propose de nous attarder maintenant sur deux items : Serre_Temp
et FrequenceTrans
. Ces deux items utilisent mosquitto que nous avons déjà présenté.
Number Serre_Temp "Température serre [%.2f]" <temperature> (Serre, Serre_Courbes) {mqtt="<[mosquitto:ElevageDeK/Jardin/Serre/1/OUT/temperature:state:default]"} Number FrequenceTrans {mqtt=">[mosquitto:ElevageDeK/Jardin/Serre/1/IN/frequence:state:*:default]"}
mosquitto
précise l'alias du courtier, >
l'envoi de données, <
la réception de données, ElevageDeK/Jardin/Serre/1/OUT/temperature
indique le fil sur lequel la lecture s'effectue, ElevageDeK/Jardin/Serre/1/IN/frequence
le fil sur lequel l'écriture se fait, state:default
le type d'informations.
Les trois items FrequenceTrans
, FrequenceAcq
et Endormissemnt
sont "liés". FrequenceAcq
est fournie par l'utilisateur, FrequenceTrans
est transmis au courtier lorsque Endormissement
est basculé. Cela évite de transmettre de façon systématique les modifications de FrequenceAcq
. Cela se fait par l'intermédiaire d'une règle, que je présente plus loin.
3.5 Configuration des fichiers xx.sitemap
Ces fichiers sont utilisés pour définir le contenu et la structure de l'interface utilisateur.
sitemap default label="ElevageDeK" { Frame label="Date" { Text item=Date } Frame label="Météo" { Text item=Meteo_Temperature valuecolor=[Meteo_LastUpdate=="NonInitialise"="lightgray",Meteo_LastUpdate>90="lightgray",>25="orange",>15="green",>5="orange",<=5="blue"] { Frame { Text item=Meteo_Temp_Max valuecolor=[>25="orange",>15="green",>5="orange",<=5="blue"] Text item=Meteo_Temp_Min valuecolor=[>25="orange",>15="green",>5="orange",<=5="blue"] Text item=Meteo_Humidite Text item=Meteo_LastUpdate } Frame label="Courbes" { Switch item=Meteo_Courbes_Periode label="Choix" mappings=[0="Heure", 1="Jour", 2="Semaine"] Chart item=Meteo_Courbes period=h label="Essai1" refresh=6000 visibility=[Meteo_Courbes_Periode==0, Meteo_Courbes_Periode=="Uninitialized"] Chart item=Meteo_Courbes period=D label="Essai2" refresh=30000 visibility=[Meteo_Courbes_Periode==1] Chart item=Meteo_Courbes period=W label="Essai3" refresh=30000 visibility=[Meteo_Courbes_Periode==2] } } } Frame label="Extérieur" { Group item=Jardin icon="garden" { Text item=Serre { Frame { Text item=Serre_Temp Text item=Serre_Humidite } Chart item=Serre_Temp period=h refresh=6000 } } } Frame label="Réglages" { Group item=SerreReglage { Frame { Setpoint item=FrequenceAcq minValue=0 maxValue=3600 step=4 Switch item=Endormissement } } } }
On reconnaît (?) la structure de l'interface présentée précédemment avec par exemple le label Météo
ou encore Température
. Ce dernier conduit à une autre page dans laquelle on trouvera les températures maximales et minimales du jour, l'humidité ainsi que l'heure de la dernière mise à jour. En dessous figure une courbe traçant l'évolution de la température et de l'humidité.
Vous aurez noté que les courbes se trace avec Chart
, il faut bien sur activer la persistance des données dans le fichier de configuration.
# The name of the default persistence service to use persistence:default=db4o
J'utilise db4o
(data base for object) qui n'est pas celui par défaut d'openHab mais j'ai rencontré des problèmes avec rr4j
.
Chart item=Meteo_Courbes period=h label="Essai1" refresh=6000 visibility=[Meteo_Courbes_Periode==0, Meteo_Courbes_Periode=="Uninitialized"]
On définit un tracé de courbe (Chart) en liaison avec le group (Meteo_Courbes
) défini dans le fichier d'items. La période affichée est horaire (period=h
) les données sont rafraichies toutes les minutes (refresh=6000
), la courbe est affichée en fonction de la valeur du sélecteur Meteo_Courbes_Periode==0
qui est affiché auparavant (Switch item=Meteo_Courbes_Periode label="Choix" mappings=[0="Heure", 1="Jour", 2="Semaine"]
).
Frame label="Réglages" { Group item=SerreReglage { Frame { Setpoint item=FrequenceAcq minValue=0 maxValue=3600 step=4 Switch item=Endormissement } } }
Ce bloc d'affichage permet d'envoyer des consignes à l'ESP Setpoint
est un slider qui permet de fixer une valeur entre 0 et 3600 secondes par pas de 4. La valeur sera réellement envoyée que lorsque le switch Endormissement
aura été basculé. La valeur est transmisse grâce à l'item FrequenceTrans
qui n’apparaît pas au niveau de l'interface mais dont la valeur est fixée par une règle.
3.6 Configuration de la persistance
Le fichier de configuration est /etc/openhab/configurations/persistence/db4o.persist
, si vous utiliser rrd4j
remplacer db4o
par ce dernier. Vous devez définir les stratégies que vous souhaitez mettre en œuvre. Le format correspond à ce que l'on fait avec les tables de planification sous Unix/Linux (crontab). Trois stratégies sont préexistantes : everyChange
, everyUpdate
et restoreOnStartup
.
Strategies { everyMinute : "0 * * * * ?" everyHour : "0 0 * * * ?" everyDay : "0 0 0 * * ?" default = everyChange } Items { * : strategy = everyChange, restoreOnStartup Meteo_Courbes* : strategy = everyMinute, restoreOnStartup Temp : strategy = everyMinute, restoreOnStartup }
L'*
est un caractère joker, et représente l'ensemble des items limités au groupe Meteo_Courbes
lorsqu'elle est associée à ce dernier, où à la totalité des items pour la première utilisation.
3.7 Configuration des règles
Le langage utilisé a des faux airs de Java, c'est en fait du xtend
import org.openhab.core.library.types.* rule "Initialise les items appartenant au groupe Initialiser" when System started then logInfo("Initialiser", "45s pour le démarrage ...") createTimer(now.plusSeconds(45)) [| logInfo("Initialiser", "... initialisation en cours") Initialiser.members.filter( x | x.state == Uninitialized).forEach[ item | postUpdate(item, 0) ] ] end rule "MAJ des données météo" when Item Meteo_Temperature received update then postUpdate(Meteo_LastUpdate, new DateTimeType()) end rule "Envoi Frequence" when Item Endormissement received command then if (receivedCommand==ON) { postUpdate(Endormissement, OFF) var int valeur = 0 if (FrequenceAcq.state instanceof DecimalType) valeur = (FrequenceAcq.state as DecimalType).intValue postUpdate(FrequenceTrans, valeur); } end
La première règle initialise les items non encore initialisés appartenant au groupe Initialiser
. La troisième règle permet de fixer la valeur de l'item FrequenceTrans
qui sera transmis à l'ESP lorsque le switch Endormissement
a basculé. Cette valeur est celle de l'item FrequenceAcq
.
3.8 Programmation de l'ESP
Il nous reste à programmer l'ESP on repart du code présenté pour l' ESP et du code écrit précédemment.