Thermostat pour piloter jusqu'à 4 radiateurs avec fil pilote
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 lines
3.5 KiB

// 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(const QHostAddress& host, const quint16 port,
QObject* parent) : QMQTT::Client(host, port, parent)
{
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();
*/
}
MQTTClient::~MQTTClient() {
}
void MQTTClient::onError(const QMQTT::ClientError error)
{
qDebug() << "error" << error;
}
void MQTTClient::onConnected()
{
qDebug() << "connected";
this->subscribe("sensors/#", 1);
}
void MQTTClient::onSubscribed(const QString& topic)
{
qDebug() << "subscribed " << topic;
}
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();
for (int i = 0; i < s->nbZones(); ++i) {
if (s->m_rooms.at(i).sensor_topic == message.topic()) {
qDebug() << "this is for us !";
sensorData = QJsonDocument::fromJson(message.payload());
if (!sensorData.isObject()) {
qWarning() << "malformed JSON data";
goto out;
}
QJsonObject obj(sensorData.object());
val = obj["temperature"];
if (val.isDouble()) {
emit new_temperature(i, val.toDouble());
qDebug() << val.toDouble();
}
val = obj["humidity"];
if (val.isDouble()) {
emit new_hygro(i, val.toDouble());
qDebug() << val.toDouble();
}
val = obj["battery"];
if (val.isDouble()) {
emit new_battery(i, val.toDouble());
qDebug() << val.toDouble();
}
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 << " topic: " << message.topic() << "payload" << QString::fromUtf8(message.payload());
}
void MQTTClient::onDisconnected(void)
{
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);
}
void MQTTClient::allHeatersOn(bool on) {
Settings *s = Settings::getInstance();
QString payload = on ? QString("1") : QString("0");
for (int i = 0; i < s->nbZones(); i++) {
const struct Room *r = &(s->m_rooms.at(i));
for (int j = 0; j < r->heaters.count(); j++) {
const struct Heater *h = &(r->heaters.at(j));
/* TODO: check if connected */
publish_msg(h->ctrl_topic, payload);
}
}
}
/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */