Add Mqtt item

This commit is contained in:
Carl Philipp Klemm 2026-04-12 18:06:19 +02:00
parent 0fd50eb227
commit eb60f85604
19 changed files with 901 additions and 48 deletions

110
src/mqttclient.cpp Normal file
View file

@ -0,0 +1,110 @@
#include "mqttclient.h"
MqttClient::MqttClient():
client(new QMqttClient)
{
}
void MqttClient::start(const QJsonObject& settings)
{
baseTopicName = settings["BaseTopic"].toString("zigbee2mqtt");
QMqttClient* cl = client.get();
connect(cl, &QMqttClient::stateChanged, this, &MqttClient::onClientStateChanged);
connect(cl, &QMqttClient::errorChanged, this, &MqttClient::onClientError);
client->setHostname(settings["Host"].toString("127.0.0.1"));
client->setPort(settings["Port"].toInt(1883));
if(settings.contains("User"))
client->setUsername(settings["User"].toString());
if(settings.contains("Password"))
client->setPassword(settings["Password"].toString());
client->setProtocolVersion(QMqttClient::MQTT_5_0);
client->connectToHost();
}
void MqttClient::onClientError(QMqttClient::ClientError error)
{
qWarning()<<"MQTT Client error:"<<error;
}
void MqttClient::onClientStateChanged(QMqttClient::ClientState state)
{
if(state == QMqttClient::ClientState::Connected)
qInfo()<<"Connected to MQTT broker at "<<client->hostname()<<client->port();
else if (state == QMqttClient::ClientState::Disconnected)
qWarning()<<"Lost connection to MQTT broker";
else if(state == QMqttClient::ClientState::Connecting)
qInfo()<<"Connecting to MQTT broker at "<<client->hostname()<<client->port();
}
void MqttClient::store(QJsonObject& json)
{
json["Host"] = client->hostname();
json["Port"] = client->port();
json["BaseTopic"] = baseTopicName;
if(client->username() != "")
json["User"] = client->username();
if(client->password() != "")
json["Password"] = client->password();
}
std::shared_ptr<QMqttClient> MqttClient::getClient()
{
return client;
}
MqttClient::Subscription* MqttClient::subscribe(QString topic)
{
if(subscriptions.contains(topic))
{
MqttClient::Subscription* sub = subscriptions[topic];
++sub->ref;
return sub;
}
else
{
qDebug()<<"MqttClient: subscibeing to"<<topic;
MqttClient::Subscription* sub = new Subscription;
sub->subscription = client->subscribe(topic);
sub->ref = 1;
subscriptions.insert({topic, sub});
return sub;
}
}
void MqttClient::unsubscribe(MqttClient::Subscription* subscription)
{
QString topic = subscription->subscription->topic().filter();
unsubscribe(topic);
}
void MqttClient::unsubscribe(QString topic)
{
assert(!subscriptions.contains(topic));
MqttClient::Subscription* sub = subscriptions[topic];
if(--sub->ref > 0)
return;
qDebug()<<"MqttClient: unsubscibeing"<<sub->subscription->topic();
client->unsubscribe(sub->subscription->topic());
subscriptions.erase(topic);
delete sub;
}
QString MqttClient::getBaseTopic()
{
return baseTopicName;
}
MqttClient::~MqttClient()
{
for(const std::pair<QString, Subscription*> sub : subscriptions)
{
qWarning()<<sub.first<<"not unregistered at exit!";
client->unsubscribe(sub.second->subscription->topic());
}
}