// SPDX-License-Identifier: GPL-3.0-or-later
|
|
/*
|
|
* Qt mutizone MQTT thermostat
|
|
*
|
|
* Copyright (C) 2019 Richard Genoud
|
|
*
|
|
*/
|
|
|
|
#include <QLoggingCategory>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonValue>
|
|
|
|
|
|
#include "mqttclient.h"
|
|
#include "settings.h"
|
|
#include "qmqtt.h"
|
|
|
|
MQTTClient *MQTTClient::_singleton = NULL;
|
|
|
|
MQTTClient *MQTTClient::getInstance(void)
|
|
{
|
|
if (!_singleton) {
|
|
Settings *s = Settings::getInstance();
|
|
|
|
_singleton = new MQTTClient(QHostAddress(s->m_broker.address), s->m_broker.port);
|
|
}
|
|
|
|
return _singleton;
|
|
}
|
|
|
|
MQTTClient::MQTTClient(const QHostAddress& host, const quint16 port,
|
|
QObject* parent) : QMQTT::Client(host, port, parent)
|
|
{
|
|
connect(this, &MQTTClient::connected, this, &MQTTClient::onConnected);
|
|
connect(this, &MQTTClient::subscribed, this, &MQTTClient::onSubscribed);
|
|
connect(this, &MQTTClient::received, this, &MQTTClient::onReceived);
|
|
connect(this, &MQTTClient::published, this, &MQTTClient::onPublished);
|
|
connect(this, &MQTTClient::error, this, &MQTTClient::onError);
|
|
|
|
connectToHost();
|
|
}
|
|
|
|
MQTTClient::~MQTTClient() {
|
|
}
|
|
|
|
void MQTTClient::onError(const QMQTT::ClientError error)
|
|
{
|
|
qDebug() << "error" << error << endl;
|
|
}
|
|
|
|
void MQTTClient::onConnected()
|
|
{
|
|
qDebug() << "connected" << endl;
|
|
this->subscribe("sensors/#", 1);
|
|
}
|
|
|
|
void MQTTClient::onSubscribed(const QString& topic)
|
|
{
|
|
qDebug() << "subscribed " << topic << endl;
|
|
}
|
|
|
|
void MQTTClient::onReceived(const QMQTT::Message& message)
|
|
{
|
|
Settings *s = Settings::getInstance();
|
|
QJsonDocument sensorData;
|
|
QJsonValue val;
|
|
|
|
qDebug() << "publish received: \"" << QString::fromUtf8(message.payload())
|
|
<< "\"" << " from: " << message.topic() << endl;
|
|
|
|
for (int i = 0; i < s->nbZones(); ++i) {
|
|
if (s->m_rooms.at(i).sensor_topic == 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());
|
|
val = obj["temperature"];
|
|
if (val.isDouble()) {
|
|
emit new_temperature(i, val.toDouble());
|
|
qDebug() << val.toDouble() << endl;
|
|
}
|
|
|
|
val = obj["humidity"];
|
|
if (val.isDouble()) {
|
|
emit new_hygro(i, val.toDouble());
|
|
qDebug() << val.toDouble() << endl;
|
|
}
|
|
|
|
val = obj["battery"];
|
|
if (val.isDouble()) {
|
|
emit new_battery(i, val.toDouble());
|
|
qDebug() << val.toDouble() << endl;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (s->m_rooms.at(i).availability_topic == message.topic()) {
|
|
|
|
emit new_availability(i, message.payload() == QString("online").toUtf8());
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
void MQTTClient::onPublished(const QMQTT::Message& message, quint16 msgid)
|
|
{
|
|
qDebug() << "published" << msgid << " payload: " << message.topic() << endl;
|
|
}
|
|
|
|
void MQTTClient::onDisconnected(void)
|
|
{
|
|
qDebug() << "disconnected" << endl;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */
|