BeeHoneyt  1.1
BTS SNIR LaSalle Avignon 2021
communication.cpp
Aller à la documentation de ce fichier.
1 #include "communication.h"
2 #include "ihmpc.h"
3 #include <QSettings>
4 #include <QDir>
5 #include <QMessageBox>
6 #include <QJsonDocument>
7 #include <QDateTime>
8 #include <QDebug>
9 
10 
23 Communication::Communication(QObject *parent) : QObject(parent), clientMqtt(new QMqttClient(this)), abonnementMqtt(nullptr)
24 {
25  qDebug() << Q_FUNC_INFO;
26 
27  configurer();
28 }
29 
35 {
36  this->deconnecter();
37  this->sauvegarder();
38  qDebug() << Q_FUNC_INFO;
39 }
40 
41 // Services ==============================================================
48 {
49  if(clientMqtt->state() == QMqttClient::Connected)
50  return true;
51  return false;
52 }
53 
60 {
61  if(clientMqtt->state() != QMqttClient::Connected)
62  {
63  qDebug() << Q_FUNC_INFO << hostname << port << username << password;
64 
65  clientMqtt->setHostname(hostname);
66  clientMqtt->setPort(port);
67  clientMqtt->setUsername(username);
68  clientMqtt->setPassword(password);
69 
70  QString message = "Connexion " + hostname;
71  emit messageJournal(message);
72  clientMqtt->connectToHost();
73 
74  connect(clientMqtt, SIGNAL(messageReceived(QByteArray,QMqttTopicName)), this, SLOT(recevoirMessage(QByteArray,QMqttTopicName)));
75  }
76 }
77 
87 void Communication::connecter(QString hostname, int port, QString username, QString password)
88 {
89  if(clientMqtt->state() != QMqttClient::Connected)
90  {
91  this->hostname = hostname;
92  this->port = port;
93  this->username = username;
94  this->password = password;
95 
96  this->connecter();
97  }
98 }
99 
106 {
107  qDebug() << Q_FUNC_INFO;
108  this->deconnecter();
109  this->connecter();
110 }
111 
121 void Communication::reconnecter(QString hostname, int port, QString username, QString password)
122 {
123  this->deconnecter();
124  this->connecter(hostname, port, username, password);
125 }
126 
133 {
134  if(clientMqtt->state() != QMqttClient::Connected)
135  return;
136  clientMqtt->disconnectFromHost();
137  QString message = "Déconnexion " + hostname;
138  emit messageJournal(message);
139  disconnect(clientMqtt, SIGNAL(messageReceived(QByteArray,QMqttTopicName)), this, SLOT(recevoirMessage(QByteArray,QMqttTopicName)));
140  qDebug() << Q_FUNC_INFO;
141 }
142 
149 bool Communication::abonner(QString deviceID)
150 {
151  if(clientMqtt->state() != QMqttClient::Connected)
152  return false;
153 
154  // Exemple de deviceID : ruche-1-sim, ruche-2-sim
155  // Format de topic TTN : ApplicationID/devices/DeviceID/up
156  // Exemple de topic : rucher/devices/ruche-1-sim/up
157 
158  QString topic = username + "/devices/" + deviceID + "/up";
159  qDebug() << Q_FUNC_INFO << deviceID << topic;
160  QMqttTopicFilter topicFilter(topic.toLatin1());
161  abonnementMqtt = clientMqtt->subscribe(topicFilter);
162  QString message = "Abonnement " + deviceID;
163  emit messageJournal(message);
164 
165  if (!abonnementMqtt)
166  {
167  QMessageBox::critical(0, "Erreur", "Impossible de s'abonner !");
168  return false;
169  }
170 
172 
173  return true;
174 }
175 
182 void Communication::desabonner(QString deviceID)
183 {
184  if(clientMqtt->state() != QMqttClient::Connected)
185  return;
189  QString topic = username + "/devices/" + deviceID + "/up";
190  qDebug() << Q_FUNC_INFO << deviceID << topic;
191  QMqttTopicFilter topicFilter(topic.toLatin1());
192  clientMqtt->unsubscribe(topicFilter);
193  QString message = "Désabonnement " + deviceID;
194  emit messageJournal(message);
195 }
202 {
203  return this->hostname;
204 }
211 {
212  return this->username;
213 }
220 {
221  return this->password;
222 }
223 
230 {
231  QSettings settings(QDir::currentPath() + "/beehoneyt.ini", QSettings::IniFormat);
232 
233  settings.beginGroup("TTN");
234  hostname = settings.value("Hostname").toString();
235  port = settings.value("Port").toInt();
236  username = settings.value("Username").toString();
237  password = settings.value("Password").toString();
238  settings.endGroup();
239  settings.sync();
240  //qDebug() << Q_FUNC_INFO << hostname << port << username << password;
241 
242  connect(clientMqtt, SIGNAL(stateChanged(ClientState)), this, SLOT(changerEtat()));
243 }
244 
251 {
252  QSettings settings(QDir::currentPath() + "/beehoneyt.ini", QSettings::IniFormat);
253 
254  settings.beginGroup("TTN");
255  settings.setValue("Hostname" , hostname);
256  settings.setValue("Port" , port);
257  settings.setValue("Username" , username);
258  settings.setValue("Password" , password);
259  settings.sync();
260 
261  //qDebug() << Q_FUNC_INFO << hostname << port << username << password;
262 }
263 
270 {
271  qDebug() << Q_FUNC_INFO << clientMqtt->state();
272  QString message;
273  switch (clientMqtt->state())
274  {
275  case QMqttClient::Disconnected:
276  qDebug() << Q_FUNC_INFO << "Déconnecté";
277  emit ttnDeconnecte();
278  message = "Déconnecté " + hostname;
279  emit messageJournal(message);
280  break;
281  case QMqttClient::Connecting:
282  qDebug() << Q_FUNC_INFO << "En cours de connexion";
283  break;
284  case QMqttClient::Connected:
285  qDebug() << Q_FUNC_INFO << "Connecté";
286  emit ttnConnecte();
287  sauvegarder();
288  message = "Connecté " + hostname;
289  emit messageJournal(message);
290  break;
291  default:
292  break;
293  }
294 }
295 
302 void Communication::recevoirMessage(const QByteArray &messageRecu, const QMqttTopicName &topic)
303 {
304  QJsonDocument documentJSON = QJsonDocument::fromJson(messageRecu);
305  QJsonObject objetJSON = documentJSON.object();
306 
307  // Extraction du deviceID et du port
308  QString deviceID = objetJSON.value(QString("dev_id")).toString();
309  int port = objetJSON.value(QString("port")).toInt();
310 
311  qDebug() << Q_FUNC_INFO << "topic" << topic;
312  qDebug() << Q_FUNC_INFO << "DeviceID " << deviceID;
313  //qDebug() << Q_FUNC_INFO << "message" << messageRecu;
314  qDebug() << Q_FUNC_INFO << "port" << port;
315 
316  // Journalisation
317 
318  QString message = "Message reçu de " + deviceID + " :\n" + messageRecu;
319  emit messageJournal(message); // Extrait d'un message reçu
320  // messageRecu contient du JSON
321  // les clés à extraire :
322  // - port : 1, 2 ou 3 précise ce que contient le payload_fields
323  // - payload_fields : données du port
324  // - horodatage (timestamp - nombre de secondes depuis le 1 janvier 1970)
325  // Exemple :
326  // "port":2
327  // "payload_fields":{"humiditeExt":32,"humiditeInt":32,"pression":1003,"temperatureExt":17.4,"temperatureInt":23.1}
328  // "timestamp":3459190155,"time":"2021-04-18T08:11:35Z"
329 
363  // Extraction de l'horodatage
364  QJsonObject messageMetadata = objetJSON.value(QString("metadata")).toObject();
365  QString valeurHorodatage = messageMetadata.value(QString("time")).toString();
366  //qDebug() << Q_FUNC_INFO << "valeurHorodatage" << valeurHorodatage;
367  QDateTime horodatage = QDateTime::fromString(valeurHorodatage, Qt::ISODate).toLocalTime();
368  qDebug() << Q_FUNC_INFO << "horodatage" << horodatage.toString("dd/MM/yyyy HH:mm:ss");
369  mesure.setHorodatage(horodatage.toString("dd/MM/yyyy HH:mm:ss"));
370 
371  // Extraction des mesures
372  QJsonObject messageMesures = objetJSON.value(QString("payload_fields")).toObject();
373  QJsonValue valeurPoids, valeurHumiditeExt, valeurHumiditeInt, valeurTemperatureExt, valeurTemperatureInt, valeurPression;
374 
375  switch (port)
376  {
377  case PORT_TTN_POIDS:
378  valeurPoids = messageMesures.value(QString("poids")).toDouble();
379 
380  mesure.setPoids(valeurPoids.toDouble());
381 
382  emit nouvellesMesures(mesure);
383  break;
385  valeurHumiditeExt = messageMesures.value(QString("humiditeExt")).toDouble();
386  valeurHumiditeInt = messageMesures.value(QString("humiditeInt")).toDouble();
387  valeurTemperatureExt = messageMesures.value(QString("temperatureExt")).toDouble();
388  valeurTemperatureInt = messageMesures.value(QString("temperatureInt")).toDouble();
389  valeurPression = messageMesures.value(QString("pression")).toDouble();
390 
391  mesure.setHumiditeExterieure(valeurHumiditeExt.toDouble());
392  mesure.setHumiditeInterieure(valeurHumiditeInt.toDouble());
393  mesure.setTemperatureExterieure(valeurTemperatureExt.toDouble());
394  mesure.setTemperatureInterieure(valeurTemperatureInt.toDouble());
395  mesure.setPression(valeurPression.toDouble());
396  //qDebug() << Q_FUNC_INFO << "mesure" << mesure.getTemperatureInterieure() << mesure.getTemperatureExterieure() << mesure.getHumiditeInterieure() << mesure.getHumiditeExterieure() << mesure.getPression();
397 
398  emit nouvellesMesures(mesure);
399  break;
400  default:
401  break;
402  }
403 }
bool abonner(QString deviceID)
Méthode qui abonne le client Mqtt à un topic , à partir du deviceID.
void recevoirMessage(const QByteArray &message, const QMqttTopicName &topic)
Méthode qui reçoit et traite le message du topic, et signal les nouvelles mesures à l&#39;IHM...
void deconnecter()
Méthode qui déconnecte le client Mqtt.
#define PORT_TTN_POIDS
Definition: communication.h:16
La déclaration de la classe Communication.
QString username
Definition: communication.h:43
void setTemperatureExterieure(double temperatureExterieure)
Methode qui change la valeur de la temperature exterieure.
Definition: mesureruche.cpp:98
QString getPassword() const
Methode qui retourne le mot de passe.
void setTemperatureInterieure(double temperatureInterieure)
Methode qui change la valeur de la temperature interieure.
Definition: mesureruche.cpp:87
QString hostname
Definition: communication.h:41
MesureRuche mesure
Definition: communication.h:45
void ttnConnecte()
void changerEtat()
Méthode qui signal l&#39;état du client Mqtt à l&#39;IHM.
~Communication()
Destructeur de la classe Communication.
void desabonner(QString deviceID)
Méthode qui désabonne le client Mqtt , à partir du deviceID.
QString password
Definition: communication.h:44
La déclaration de la classe IHMPc.
QString getHostname() const
Methode qui retourne le nom d&#39;hote.
void ttnDeconnecte()
void setHumiditeExterieure(double humiditeExterieure)
Methode qui change la valeur de l&#39;humidite exterieure.
void connecter()
Méthode qui connecte le client Mqtt (par défaut) et permet la récupération du message (à l&#39;aide de la...
void setPression(double pression)
Methode qui change la valeur de la pression.
bool estConnecte() const
Méthode qui retourne une valeur booléene true si le client Mqtt est connecté
void configurer()
Méthode qui configure le client Mqtt , à partir du fichier beehoneyt.ini.
void setHumiditeInterieure(double humiditeInterieure)
Methode qui change la valeur de l&#39;humidite interieure.
void nouvellesMesures(MesureRuche mesure)
QMqttSubscription * abonnementMqtt
Definition: communication.h:40
QString getUsername() const
Methode qui retourne le nom d&#39;utilisateur.
void initialiser()
Methode qui intialise les attributs.
Definition: mesureruche.cpp:69
void messageJournal(QString message)
#define PORT_TTN_ENVIRONNEMENT
Definition: communication.h:17
void setHorodatage(QString horodatage)
Methode qui change la valeur de l&#39;horodatage.
void setPoids(double poids)
Methode qui change la valeur du poids.
QMqttClient * clientMqtt
Definition: communication.h:39
void reconnecter()
Méthode qui déconnecte puis connecte le client Mqtt.
Communication(QObject *parent=nullptr)
Constructeur de la classe Communication.
void sauvegarder()
Méthode qui sauvegarde la configuration du client Mqtt , dans le fichier beehoneyt.ini.