diff --git a/soft/thermostat/INSTALL b/soft/thermostat/INSTALL index 6d44c72..4bc5ddb 100644 --- a/soft/thermostat/INSTALL +++ b/soft/thermostat/INSTALL @@ -1,8 +1,7 @@ Dependencies: -sudo apt install qttools5-dev-tools qt5-default -git clone https://github.com/emqx/qmqtt.git +sudo apt install qttools5-dev-tools qt5-default qtbase5-private-dev +git clone https://github.com/qt/qtmqtt.git cd qmqtt -qmake && make -j +git checkout v$(qmake -v | grep "Qt version" | sed "s/^.*version \([5-9]\.[0-9]\+\.[0-9]\+\) .*$/\1/") || echo "Unable to find your Qt version" +qmake && make -j$(nproc) sudo make install - - diff --git a/soft/thermostat/inc/mqttclient.h b/soft/thermostat/inc/mqttclient.h index c845589..8de4bf2 100644 --- a/soft/thermostat/inc/mqttclient.h +++ b/soft/thermostat/inc/mqttclient.h @@ -9,18 +9,16 @@ #ifndef MQTTCLIENT_H #define MQTTCLIENT_H -#include #include -#include "qmqtt.h" +#include -class MQTTClient: public QMQTT::Client +class MQTTClient: public QMqttClient { Q_OBJECT public: - explicit MQTTClient(const QHostAddress& host = QHostAddress::LocalHost, - const quint16 port = 1883, - QObject* parent = NULL); + explicit MQTTClient(const QString& host = "localhost", int port = 1883, + QObject* parent = NULL); virtual ~MQTTClient(); void publish_msg(const QString& topic, const QString& payload); @@ -29,10 +27,10 @@ private: public slots: void onConnected(); - void onSubscribed(const QString& topic); - void onReceived(const QMQTT::Message& message); - void onError(const QMQTT::ClientError error); - void onPublished(const QMQTT::Message& message, quint16 msgid); + void onReceived(const QByteArray &message, const QMqttTopicName &topic); + void onError(ClientError error); + void onPublished(qint32 msgid); + void onStateChanged(ClientState state); void onDisconnected(void); void allHeatersOn(bool on); diff --git a/soft/thermostat/src/mainwindow.cpp b/soft/thermostat/src/mainwindow.cpp index d9fa103..8eaabad 100644 --- a/soft/thermostat/src/mainwindow.cpp +++ b/soft/thermostat/src/mainwindow.cpp @@ -84,7 +84,7 @@ MainWindow::MainWindow(QWidget *parent) : /* * MQTT client */ - m_mqtt = new MQTTClient(QHostAddress(s->m_broker.address), s->m_broker.port, NULL); + m_mqtt = new MQTTClient(s->m_broker.address, s->m_broker.port, NULL); m_mqtt->connectToHost(); diff --git a/soft/thermostat/src/mqttclient.cpp b/soft/thermostat/src/mqttclient.cpp index bd2c620..2a0b70a 100644 --- a/soft/thermostat/src/mqttclient.cpp +++ b/soft/thermostat/src/mqttclient.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -14,57 +15,76 @@ #include "mqttclient.h" #include "settings.h" -#include "qmqtt.h" -MQTTClient::MQTTClient(const QHostAddress& host, const quint16 port, - QObject* parent) : QMQTT::Client(host, port, parent) +MQTTClient::MQTTClient(const QString& host, int port, QObject* parent) + : QMqttClient(parent) { + this->setHostname(host); + this->setPort(port); + connect(this, SIGNAL(connected(void)), this, SLOT(onConnected(void))); - connect(this, SIGNAL(subscribed(const QString&)), this, SLOT(onSubscribed(const QString&))); - connect(this, SIGNAL(received(const QMQTT::Message&)), this, SLOT(onReceived(const QMQTT::Message&))); - connect(this, SIGNAL(published(const QMQTT::Message&, quint16)), this, SLOT(onPublished(const QMQTT::Message&, quint16))); - connect(this, SIGNAL(error(const QMQTT::ClientError)), this, SLOT(onError(const QMQTT::ClientError))); - - /* - * 2 more signals: - * void unsubscribed(const QString& topic); - * void disconnected(void); - * void pingresp(); - */ + connect(this, SIGNAL(disconnected(void)), this, SLOT(onDisconnected(void))); + connect(this, SIGNAL(messageReceived(const QByteArray &, const QMqttTopicName &)), + this, SLOT(onReceived(const QByteArray &, const QMqttTopicName &))); + connect(this, SIGNAL(messageSent(qint32)), this, SLOT(onPublished(qint32))); + connect(this, SIGNAL(errorChanged(ClientError)), + this, SLOT(onError(ClientError))); + connect(this, SIGNAL(stateChanged(ClientState)), + this, SLOT(onStateChanged(ClientState))); + } MQTTClient::~MQTTClient() { } -void MQTTClient::onError(const QMQTT::ClientError error) +void MQTTClient::onStateChanged(ClientState state) { - qDebug() << "error" << error; + qDebug() << "mqtt state " << state; + switch (state) { + case Disconnected: break; + case Connecting: break; + case Connected: break; + default: break; + } } -void MQTTClient::onConnected() +void MQTTClient::onError(ClientError error) { - qDebug() << "connected"; - this->subscribe("sensors/#", 1); + qDebug() << "mqtt error " << error; + /* TODO */ + switch (error) { + case NoError: break; + case InvalidProtocolVersion: break; + case IdRejected: break; + case ServerUnavailable: break; + case BadUsernameOrPassword: break; + case NotAuthorized: break; + case TransportInvalid: break; + case ProtocolViolation: break; + case UnknownError: break; + default: break; + } } -void MQTTClient::onSubscribed(const QString& topic) +void MQTTClient::onConnected() { - qDebug() << "subscribed " << topic; + qDebug() << "connected"; + this->subscribe(QString("sensors/#"), 1); } -void MQTTClient::onReceived(const QMQTT::Message& message) +void MQTTClient::onReceived(const QByteArray &message, const QMqttTopicName &topic) { Settings *s = Settings::getInstance(); QJsonDocument sensorData; QJsonValue val; - qDebug() << "publish received: \"" << QString::fromUtf8(message.payload()) - << "\"" << " from: " << message.topic(); + qDebug() << "publish received: \"" << QString::fromUtf8(message) + << "\"" << " from: " << topic.name(); for (int i = 0; i < s->nbZones(); ++i) { - if (s->m_rooms.at(i).sensor_topic == message.topic()) { + if (s->m_rooms.at(i).sensor_topic == topic.name()) { qDebug() << "this is for us !"; - sensorData = QJsonDocument::fromJson(message.payload()); + sensorData = QJsonDocument::fromJson(message); if (!sensorData.isObject()) { qWarning() << "malformed JSON data"; goto out; @@ -91,31 +111,34 @@ void MQTTClient::onReceived(const QMQTT::Message& message) break; } - if (s->m_rooms.at(i).availability_topic == message.topic()) { + if (s->m_rooms.at(i).availability_topic == topic.name()) { - emit new_availability(i, message.payload() == QString("online").toUtf8()); + emit new_availability(i, message == QString("online").toUtf8()); } } out: return; } -void MQTTClient::onPublished(const QMQTT::Message& message, quint16 msgid) +void MQTTClient::onPublished(qint32 msgid) { - qDebug() << "published" << msgid << " topic: " << message.topic() << "payload" << QString::fromUtf8(message.payload()); + qDebug() << "published id " << msgid; } void MQTTClient::onDisconnected(void) { + /* TODO */ qDebug() << "disconnected"; } void MQTTClient::publish_msg(const QString& topic, const QString& payload) { - // id is automatically incremented if ==0 and QoS>0 - // DUP: if a message is resent, it should have the DUP flag - QMQTT::Message message(0, topic, payload.toUtf8(), 1, true, false); - publish(message); + qint32 msgid; + + msgid = this->publish(QMqttTopicName(topic), payload.toUtf8(), 1, true); + if (msgid == -1) { + qDebug() << "fail to publish message " << payload << " on " << topic; + } } void MQTTClient::allHeatersOn(bool on) { diff --git a/soft/thermostat/thermostat.pro b/soft/thermostat/thermostat.pro index f9cc0cf..349ec6f 100644 --- a/soft/thermostat/thermostat.pro +++ b/soft/thermostat/thermostat.pro @@ -1,6 +1,6 @@ QT += core gui network -QT += qmqtt +QT += mqtt greaterThan(QT_MAJOR_VERSION, 4): QT += widgets