Cours:QtMqtt

De troyesGEII
Aller à : navigation, rechercher

Qt et MQTT

Nous utiliserons le module QtMqtt pour utiliser le protocole mqtt.

Voici les différentes étapes qui permettront de :

  • se connecter sur un broker
  • publier des messages sur des topics
  • recevoir des messages d'un topic particulier

Principe général

Configuration du projet

Ajouter dans le fichier de configuration de votre projet Qt ( fichier .pro ) la ligne suivante :

QT += mqtt

Etape 1 : connexion au broker

Dans la classe qui utilisera la connexion mqtt :

  • créer un attribut de type QMqttClient (on notera client cet attribut par la suite)
  • configurer le client en utilisant les méthodes (dans le constructeur de la classe de l'attribut en général) :
    • setHostname (ex client.setHostname("192.168.0.182"); )
    • setPort (en général port 1883 )
    • éventuellement il y a des méthodes pour s'identifier ( user / password ) sur le broker
  • établir la connexion :
    • on appelle la méthode connectToHost qui essaie d'établir une connexion
    • le client émet le signal connected lorsque la connexion est réussie
    • rque : on peut éventuellement utiliser un QTimer pour faire une tentative de connexion régulièrement jusqu'à réussite
  • complément : perte de connexion [facultatif dans un 1er temps]
    • le client émettra le signal disconnected
    • on pourra alors procéder à une reconnexion (éventuellement/obligatoirement en boucle avec un QTimer)


Etape 2 : publier

Une fois connecté, on peut publier des messages. On doit indiquer :

  • le topic sur lequel on poste le message
  • le contenu du message
  • éventuellement
    • la qualité de service (qos) :
      • 0 : pas de garantie de publication du message
      • 1 : garantie que le message est bien publié au moins une fois
      • 2 : garantie de l'unicité du message
    • retain : indique si la dernière valeur publiée est sauvegardée sur le broker


Pour publier, on utiliser la méthode publish. Ex :

client.publish(QMqttTopicName("test"),"value",0,false);

Etape 3 : souscrire

Pour souscrire, nous avons besoin d'un pointeur sur un objet de type QMqttSubscription :

  • on ajoute un attribut (ou plusieurs) de type QMqttSubscription * (on notera ici souscription)
  • on attend la connexion sur le serveur
  • on utilise la méthode subscribe de la classe QMqttClient en précisant :
    • le topic : QMqttTopicFilter("test")
    • la qos (cf plus haut)
    • elle retourne un pointeur de QMqttSubscription
    • ex : souscription=client.subscribe(QMqttTopicFilter("test"),1);
  • à chaque nouveau message, l'attribut souscription émettra le signal messageReceived :
    • avec un paramètre de type QMqttMessage
    • on pourra récupérer le contenu (charge utile/payload) avec la méthode payload
    • ex : qDebug()<<message.payload();

HomeAssistant et MQTT

Capteur

Ajouter un capteur sur HomeAssistant

https://www.home-assistant.io/integrations/binary_sensor.mqtt/


   QString topic="homeassistant/binary_sensor/%1/config";
   QString payload="{\"name\": \"%1\", \
             \"unique_id\": \"%1\", \
             \"state_topic\": \"homeassistant/binary_sensor/%1/state\"\
            }";
   client.publish( QMqttTopicName(topic.arg("test")),payload.arg("test").toLatin1(), 1,false);

Supprimer un capteur sur HomeAssistant

   QString topic="homeassistant/sensor/%1/config";
   QString payload="{\"name\": \"%1\", \
             \"unique_id\": \"%1\", \
             \"state_topic\": \"homeassistant/sensor/%1/state\", \
             \"device_class\":\"%2\", \
             \"unit_of_measurement\":\"%3\" \
            }";
   client.publish( QMqttTopicName(topic.arg("test")),
                   "",
                   1,false);

Publier la valeur du capteur sur HomeAssistant

   QString topic="homeassistant/binary_sensor/%1/state";
   QString payload;
   if (value==false) payload="OFF";
   else              payload="ON";


   client.publish( QMqttTopicName(topic.arg(name)),payload.toLatin1(), 1,false);


Actionneur sur HomeAssistant

Création de l'actionneur

   QString topic="homeassistant/switch/%1/config";
   QString setTopic="homeassistant/switch/%1/set";
   QString payload="{\"name\": \"%1\", \
             \"unique_id\": \"%1\", \
             \"command_topic\": \"homeassistant/switch/%1/set\", \
             \"state_topic\": \"homeassistant/switch/%1/state\"\
            }";
   client.publish( QMqttTopicName(topic.arg("test")),payload.arg("test").toLatin1(), 1,false);


modifier l'état de l'actionneur

   QMqttSubscription * subs = client.subscribe(setTopic.arg("test"),1);
  connect(subs,&QMqttSubscription::messageReceived,???,&XXXX:getMessage);


  void XXXX::getMessage(QMqttMessage message)
  {
     qDebug()<<message.payload(); // 2 valeurs possibles ON et OFF
  }


publier l'état de l'actionneur

   QString topic="homeassistant/switch/%1/state";
   ...
   client.publish( QMqttTopicName(topic.arg(name)), "ON" ou "OFF", 1,false);

Docs

Suppléments

MQTT pour Qt : https://doc.qt.io/QtMQTT/qtmqtt-index.html

MQTT pour Arduino : https://pubsubclient.knolleary.net

NanoPi avec NodeRed ou QT

Adresses IP pour cartes Arduino : 10.98.9.XXX avec XXX = 211, 212, 213, 214 ou 215. Changer également l'adresse MAC pour la différencier des autres cartes.

Adresse broker mosquitto : 10.98.35.245