// SPDX-License-Identifier: GPL-3.0-or-later /* * Qt mutizone MQTT thermostat * * Copyright (C) 2019 Richard Genoud * */ #include #include #include #include #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: */