Faire communiquer Jeedom et un Arduino en DIY

Pour ceux qui ont lu mes précédents articles, vous savez que j’utilise Jeedouino pour faire communiquer mon Jeedom (RPI2) à mes Arduino (Mega, Uno, Nano).

En effet, il existe deux solutions (plugins) sur le jeedom-market :

  • Jeedouino : que j’utilise en production
  • Arduidom : que je n’ai jamais réussi à faire fonctionner, pourtant j’ai essayé…

Oui mais Jeedouino a des limites :

  • Pas de sketch perso de prévu (contrairement à Arduidom)
  • Gestion de certains capteurs (DHT, DS18B20) mais pas d autres (Afficheur TM1637, Afficheur LCD1602, Emetteur/récepteur RF433, etc)
  • et surtout… ça plante régulièrement

Je ne sais pas si c’est que moi, mais mes Arduinos avec Jeedouino s’arrêtent régulièrement de pinguer puis ça repart au bout de quelques secondes, ce qui par conséquent, ne fait pas remonter les états par moment, ou n’exécutent pas les actions.

Bref, je me suis décidé hier à coder une solution « home made ». Ce ne sera pas pour concurrencer les deux plugins du market (qui se veulent configurable par n’importe qui sans trop de connaissance à contrario de mon code qui sera dédié à ma configuration/mes besoins) mais plus pour le challenge, plaisir perso… et puis que cela arrête de planter (bah oui, je supervise les équipements réseaux, et quand il y en a un qui ne pingue pas pendant X min, je reçois une alerte, mais ça c’est une autre histoire).

Cela peut intéresser des personnes souhaitant faire la même chose, donc je publie ici mes premiers tests.

Ce mini-projet se décompose en deux parties :

  1. Arduino –> Jeedom : Création d’un premier sketch pour lire mes capteurs (donc remontée d’information de l’Arduino vers Jeedom). Oui je commence par le plus simple…
  2. Jeedom –> Arduino : Evolution du sketch pour le passage d’ordre à des actionneurs (relais, emetteur RF, calcul distance, etc)

1/ La lecture de capteur relié à un Arduino et transmission à Jeedom

Pour moi, il y a trois façons de faire :

  • créer un langage de communication spécifique qui sera compris de part et d autres. Trop complexe pour un débutant comme moi, il faudrait surtout que je développe également du côté Jeedom : j’oublie
  • utiliser le plugin « Virtuel » pour la remontée des informations : un serveur Web sur l’Arduino fait des requêtes GET sur le serveur Jeedom, qui les interprète via le plugin ‘Virtuel’.
  • utiliser un fichier XML pour la remontée des informations : un serveur Web sur l’Arduino reçoit une requête HTTP de Jeedom, et renvoi un fichier XML en retour, avec l’état de tous les capteurs.

Par facilité, j’ai choisi d’expérimenter les deux dernières solutions.

A/ Plugin Virtuel et serveur Web Arduino

Dans un premier temps, il faut installer le plugin « Virtuel ». Une fois installé, on créé un équipement ainsi qu’une « info virtuelle ». Une fois enregistré, on obtient son « ID » (le dièse, colonne de gauche).

Arduino : info virtuelle dans jeedom

Il nous faudra également la clé API jeedom que vous trouverez dans le panneau d’administration.

Maintenant, réalisation d’un sketch que l’on téléversera dans notre Arduino. Exemple avec une sonde DHT11 (température+humidité), un afficheur 4 digit TM1637, un Arduino Uno et son Shield Ethernet v2.

Le principe est assez simple :

  1. dans le setup, on initialise tout ce qui va bien (sonde+afficheur+client web)
  2. dans le loop :
    toutes les 30 sec on fait :

    • un relevé de la sonde DHT11
    • si les valeurs ont changé depuis le dernier passage : on envoi les données à Jeedom
    • puis on affiche la température sur l’afficheur

Ce qui donne ce résultat (cliquez ici pour voir le code du sketch).

Attention, je ne suis pas un professionnel de la programmation, il y a peut être des erreurs, et surement des optimisations de code à faire. Mais le principal pour moi, c’est que cela marche, et sans erreur constatée.

B/ Fichier XML et serveur Web Arduino

Dans cette variante, nous aurons besoin d’installer le plugin « Script ». Une fois installé, on créera un équipement, ainsi que des commandes. Chaque commande permettra de parser le fichier XML récupéré. Dans « Requête », c’est les données que vous souhaitez parser. Il faudra donc autant de commandes, avec des requêtes différentes, qu’il y a de données différentes à récupérer dans le fichier XML :

Arduino - parser fichier xml

Maintenant, réalisation d’un sketch que l’on téléversera dans notre Arduino. Toujours le même exemple avec une sonde DHT11 (température+humidité), un afficheur 4 digit TM1637, un Arduino Uno et son Shield Ethernet v2. Principe :

  1. dans le setup, on initialise tout ce qui va bien (sonde+afficheur+client web)
  2. dans le loop :
    • on écoute le port 80, si un client s’est connecté (jeedom dans notre cas), on lui envoi le fichier XML avec les données de la sonde DHT11
    • toutes les 30 sec on fait :
      • un relevé de la sonde DHT11
      • puis on affiche la température sur l’afficheur

Ce qui donne ce résultat (cliquez ici pour voir le code du sketch).

Les deux solutions ont été confrontés pendant plusieurs jours : les deux fonctionnent bien.

2/ Déclencher une action sur l’Arduino depuis Jeedom

Rappelez vous, à l’étape 1 (lecture capteur) j’avais opté pour une solution qui ne nécessitait pas de créer un langage de communication. C’est arrivé à cette étape 2 que je me dis que cela aurait été quand même bien… mais en même temps, tellement plus compliqué. Donc non, j’ai fait le bon choix ! : )

J’ai développé un petit code qui tourne très bien depuis 1 mois sur 2 de mes Arduinos (réception capteur + envoi de déclenchement de relais + envoi trame RF433MHz) ! Mais par manque de temps, je n’ai pas encore complété la fin de cet article, ni même publié le code intégral (il faut que j’enlève tout le superflus, que je commente un peu mon code, etc)… mais en attendant voici le principe :

  • toutes les 5 secondes, je regarde si j’ai reçu une requête HTTP sur le serveur web de l’Arduino
  • si j’ai reçu une requête (normalement généré par le plugin ‘Script’ de Jeedom), je regarde le 6ième caractère reçu (celui après « GET / »)
  • ce caractère définit l’action que l’Arduino devra exécuter (ouvrir/fermer un relais, envoyer une trame RF, etc)
  • cette requête HTTP est envoyé par Jeedom via ‘Script’, il faut donc définir un équipement avec différentes commandes… et bien penser à modifier le 6ième caractère en fonction de l’action que l’on veut envoyer à l’Arduino

Dans le plugin ‘Script’ de Jeedom, on aura :

Plugin script de Jeedom

Voici la fonction de lecture qui est appelée toutes les 5 sec :

// Fonction pour lire les requêtes HTTP qui arrivent sur le serveur WEB de l'Arduino
void LireTrame()
{
  // On créé l'objet pour voir si l'on reçoit quelque chose
  EthernetClient clientIncoming = server.available();
  // Si on a reçu une requête HTTP
  if (clientIncoming) 
  {
    // Pour compter les 15 premiers caractères de la réponse du serveur
    int CompteurCodeHTTP = 0;
    char MessageRecu[20] = "";
       
    boolean currentLineIsBlank = true;

    // Tant que le client est connecté
    while (clientIncoming.connected()) 
    {
      // S'il y a quelque chose à lire en arrivée
      if (clientIncoming.available()) 
      {
        char c = clientIncoming.read();
        if (c == '\n') {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }
        if (CompteurCodeHTTP <= 15)
        {
          Serial.print(c);
          CompteurCodeHTTP++;
          MessageRecu[CompteurCodeHTTP] =  c ;
        }
        
        // Pour la gestion des actionneurs, on lit la valeur juste après "GET /" (6ième caractère reçu dans la requête HTTP)
        if (CompteurCodeHTTP==6)
        {
          // Convertit le char en int, pour pouvoir utiliser le switch --> le '0' correspondant à 48 en ASCII
          int a = c  - '0' ;
          switch(a)
          {
            case 4 : // Si le 6ième caractère reçu est le "4", on allume le ventilateur
              {
                Serial.println(F("Ventilateur : ON"));
                digitalWrite(8, HIGH);
              }
              break;
            case 5 : // Si le 6ième caractère reçu est le "5", on éteint le ventilateur
              {
                Serial.println(F("Ventilateur : OFF"));
                digitalWrite(8, LOW);
              }
              break;
            default :
              {
              Serial.println(F("DEFAUT dans le switch, aucun cas ne correspond!"));
              }
              break;
          } // fin de switch
        } // Fin du SI pour interprétation du 6ième caractère
        
        // Si on reçoit un retour à la ligne et que la ligne est blanche, c'est que la requête est finie
        // on renvoi donc une réponse HTTP 200
         if (c == '\n' && currentLineIsBlank) 
        {
          clientIncoming.println("HTTP/1.1 200 OK");
          clientIncoming.println("Content-Type: text/xml");
          clientIncoming.println("Connection: close");
          clientIncoming.println();
         
          break;
        }
      } // FIN de ' S'il y a quelque chose à lire en arrivée'
    } // FIN de 'Tant que le client est connecté'
    
    Serial.println();
    // On donne le temps au serveur distant de recevoir la réponse HTTP
    delay(20);
    // close the connection:
    clientIncoming.stop();
  }
}
Fonction pour lire la requête HTTP

Dans cet exemple simplifié, on est limité à 10 actions possibles (6ième caractère = 0 à 9). Mais il est facile de rajouter l’interprétation du 7ième, 8ième, … caractères pour avoir plus que 10 actions possibles.

Finalement, on peut donc créer facilement un langage de communication HomeMade entre l’Arduino et Jeedom, pour lire des capteurs ou agit sur des actionneurs.


Cet article fait partie d’une série d’articles sur la box domotique Jeedom, les micro-contrôleurs Arduino et compatible, le tout en DIY (Do It Yourself). Consultez la liste complète des articles de cette thématique en cliquant ici.


Si vous souhaitez partager cet article...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter