diff --git a/soft/thermostat/inc/backgroundloop.h b/soft/thermostat/inc/backgroundloop.h index 74700fc..050e64b 100644 --- a/soft/thermostat/inc/backgroundloop.h +++ b/soft/thermostat/inc/backgroundloop.h @@ -11,9 +11,6 @@ #include -#include "qmqtt.h" - - class BackgroundLoop : public QThread { Q_OBJECT @@ -22,19 +19,9 @@ class BackgroundLoop : public QThread public: BackgroundLoop(); ~BackgroundLoop(); - bool connectMQTT(); private: void run() override; - QMQTT::Client *m_mqtt_client; - -private slots: - void mqtt_connected(void); - void mqtt_disconnected(void); - void mqtt_error(const QMQTT::ClientError error); - void mqtt_subscribed(const QString& topic, const quint8 qos); - void mqtt_received(const QMQTT::Message& message); - }; #endif // BACKGROUNDLOOP_H diff --git a/soft/thermostat/inc/mqttclient.h b/soft/thermostat/inc/mqttclient.h new file mode 100644 index 0000000..8419b71 --- /dev/null +++ b/soft/thermostat/inc/mqttclient.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + * Qt mutizone MQTT thermostat + * + * Copyright (C) 2019 Richard Genoud + * + */ + +#ifndef MQTTCLIENT_H +#define MQTTCLIENT_H + +#include +#include + +#include "qmqtt.h" + +class MQTTSubcriber: public QMQTT::Client +{ + Q_OBJECT +public: + explicit MQTTSubcriber(const QHostAddress& host = QHostAddress::LocalHost, + const quint16 port = 1883, + QObject* parent = NULL); + virtual ~MQTTSubcriber(); + +public slots: + void onConnected(); + void onSubscribed(const QString& topic); + void onReceived(const QMQTT::Message& message); +private: + QStringList m_sensor_topics; + QStringList m_availability_topics; +}; + +#endif + +/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */ diff --git a/soft/thermostat/src/backgroundloop.cpp b/soft/thermostat/src/backgroundloop.cpp index 991259f..563a426 100644 --- a/soft/thermostat/src/backgroundloop.cpp +++ b/soft/thermostat/src/backgroundloop.cpp @@ -14,16 +14,8 @@ #include -#include "qmqtt.h" #include "backgroundloop.h" -#define MQTT_SERVER "nas" -#define MQTT_PORT 1883 -#define MQTT_USERNAME "" -#define MQTT_PASSWORD "" -#define MQTT_CLIENT_ID "" -#define LOOP_SLEEP_TIME_S 5 - BackgroundLoop::BackgroundLoop() { m_mqtt_client = NULL; @@ -33,91 +25,8 @@ BackgroundLoop::BackgroundLoop() { BackgroundLoop::~BackgroundLoop() { } -bool BackgroundLoop::connectMQTT() -{ - QHostInfo info; - QHostAddress address; - bool result = false, ok; - - if (m_mqtt_client) { - delete m_mqtt_client; - m_mqtt_client = NULL; - } - - ok = address.setAddress(MQTT_SERVER); - if (!ok) { - /* This must be a domain name, not an IP */ - info = QHostInfo::fromName(MQTT_SERVER); - if (info.error() != QHostInfo::NoError) { - qWarning() << QString("Error looking for address %1").arg(MQTT_SERVER) - << info.errorString(); - goto out; - } - if (info.addresses().isEmpty()) { - qWarning() << QString("No address returned for %1").arg(MQTT_SERVER); - goto out; - } - address = info.addresses().first(); - } - - m_mqtt_client = new QMQTT::Client(address, MQTT_PORT); - if (!m_mqtt_client) { - qWarning() << QString("Error allocating memory for MQTT client"); - goto out; - } - if (QString(MQTT_CLIENT_ID).isEmpty()) { - m_mqtt_client->setClientId(QString("thermostat%1").arg(qrand())); - } else { - m_mqtt_client->setClientId(MQTT_CLIENT_ID); - } - connect(m_mqtt_client, SIGNAL(connected()), this, SLOT(mqtt_connected())); - connect(m_mqtt_client, SIGNAL(disconnected()), this, SLOT(mqtt_disconnected())); - connect(m_mqtt_client, SIGNAL(error(const QMQTT::ClientError)), - this, SLOT(mqtt_error(const QMQTT::ClientError))); - connect(m_mqtt_client, SIGNAL(subscribed(const QString&, const quint8)), - this, SLOT(mqtt_subscribed(const QString&, const quint8))); - connect(m_mqtt_client, SIGNAL(received(const QMQTT::Message&)), - this, SLOT(mqtt_received(const QMQTT::Message&))); - - m_mqtt_client->setUsername(MQTT_USERNAME); - m_mqtt_client->setPassword(MQTT_PASSWORD); - m_mqtt_client->connectToHost(); - - result = true; - -out: - return result; -} - -void BackgroundLoop::mqtt_connected(void) -{ - qDebug() << "MQTT connected !"; -} - -void BackgroundLoop::mqtt_disconnected(void) -{ - qDebug() << "MQTT disconnected !"; -} - -void BackgroundLoop::mqtt_error(const QMQTT::ClientError error) -{ - qDebug() << "MQTT error ! code: " << error; -} - -void BackgroundLoop::mqtt_subscribed(const QString& topic, const quint8 qos) -{ - qDebug() << "MQTT subscribed! topic: " << topic << " QoS: " << qos; -} - -void BackgroundLoop::mqtt_received(const QMQTT::Message& message) -{ - qDebug() << "MQTT recieved: " << QString::fromUtf8(message.payload()); -} - - void BackgroundLoop::run() { - connectMQTT(); while(!isInterruptionRequested()) { this->sleep(LOOP_SLEEP_TIME_S); } diff --git a/soft/thermostat/src/main.cpp b/soft/thermostat/src/main.cpp index cd26708..1f3c25b 100644 --- a/soft/thermostat/src/main.cpp +++ b/soft/thermostat/src/main.cpp @@ -17,6 +17,7 @@ int main(int argc, char *argv[]) { QTranslator qtTranslator; QTranslator translator; + MQTTSubcriber mqttclient(QHostAddress("192.168.1.2"), 1883); Q_INIT_RESOURCE(thermostat); @@ -36,6 +37,8 @@ int main(int argc, char *argv[]) MainWindow w; w.show(); + mqttclient.connectToHost(); + return a.exec(); } diff --git a/soft/thermostat/src/mqttclient.cpp b/soft/thermostat/src/mqttclient.cpp new file mode 100644 index 0000000..1aa0d1e --- /dev/null +++ b/soft/thermostat/src/mqttclient.cpp @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + * Qt mutizone MQTT thermostat + * + * Copyright (C) 2019 Richard Genoud + * + */ + +#include +#include +#include +#include +#include + + +#include "mqttclient.h" +#include "qmqtt.h" + +MQTTSubcriber::MQTTSubcriber(const QHostAddress& host, const quint16 port, + QObject* parent) : QMQTT::Client(host, port, parent) +{ + connect(this, &MQTTSubcriber::connected, this, &MQTTSubcriber::onConnected); + connect(this, &MQTTSubcriber::subscribed, this, &MQTTSubcriber::onSubscribed); + connect(this, &MQTTSubcriber::received, this, &MQTTSubcriber::onReceived); + m_sensor_topics << QString::fromUtf8("sensors/chambre_so/xiaomi"); + m_sensor_topics << QString::fromUtf8("sensors/chambre_rico/xiaomi"); + m_sensor_topics << QString::fromUtf8("sensors/salon/xiaomi"); + m_sensor_topics << QString::fromUtf8("sensors/salle_de_bains/xiaomi"); + m_availability_topics << QString::fromUtf8("sensors/chambre_so/availability"); + m_availability_topics << QString::fromUtf8("sensors/chambre_rico/availability"); + m_availability_topics << QString::fromUtf8("sensors/salon/availability"); + m_availability_topics << QString::fromUtf8("sensors/salle_de_bains/availability"); + + qDebug() << "created" << endl; +} + +MQTTSubcriber::~MQTTSubcriber() { +} + +void MQTTSubcriber::onConnected() +{ + qDebug() << "connected" << endl; + this->subscribe("sensors/#", 1); +} + +void MQTTSubcriber::onSubscribed(const QString& topic) +{ + qDebug() << "subscribed " << topic << endl; +} + +void MQTTSubcriber::onReceived(const QMQTT::Message& message) +{ + QJsonDocument sensorData; + + qDebug() << "publish received: \"" << QString::fromUtf8(message.payload()) + << "\"" << " from: " << message.topic() << endl; + + for (int i = 0; i < m_sensor_topics.size(); ++i) { + if (m_sensor_topics.at(i) == message.topic()) { + qDebug() << "this is for us !" << endl; + sensorData = QJsonDocument::fromJson(message.payload()); + if (!sensorData.isObject()) { + qWarning() << "malformed JSON data" << endl; + goto out; + } + QJsonObject obj(sensorData.object()); + QJsonValue val = obj["temperature"]; + + qDebug() << val.toDouble() << endl; + + break; + } + } +out: + return; +} + +/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */ diff --git a/soft/thermostat/thermostat.pro b/soft/thermostat/thermostat.pro index 8f8d829..8d5a537 100644 --- a/soft/thermostat/thermostat.pro +++ b/soft/thermostat/thermostat.pro @@ -24,11 +24,13 @@ SOURCES += src/main.cpp \ src/mainwindow.cpp \ src/zoneitem.cpp \ src/backgroundloop.cpp \ + src/mqttclient.cpp \ HEADERS += inc/mainwindow.h \ inc/zoneitem.h \ inc/backgroundloop.h \ + inc/mqttclient.h \ RESOURCES += thermostat.qrc