add mqtt control
This commit is contained in:
152
src/mqttcontroller.cpp
Normal file
152
src/mqttcontroller.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "mqttcontroller.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QMetaObject>
|
||||
|
||||
#include <mosquitto.h>
|
||||
|
||||
namespace {
|
||||
bool g_mqttInitialized = false;
|
||||
}
|
||||
|
||||
MqttController::MqttController(const MqttConfig &configIn, QObject *parent)
|
||||
: QObject(parent),
|
||||
config(configIn)
|
||||
{
|
||||
if (!g_mqttInitialized)
|
||||
{
|
||||
mosquitto_lib_init();
|
||||
g_mqttInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
MqttController::~MqttController()
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
mosquitto_disconnect(client);
|
||||
mosquitto_loop_stop(client, true);
|
||||
mosquitto_destroy(client);
|
||||
client = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MqttController::start()
|
||||
{
|
||||
if (!config.enabled)
|
||||
{
|
||||
Log("MQTT disabled or missing host/topic.");
|
||||
return;
|
||||
}
|
||||
|
||||
QString clientId = QString::fromStdString(config.clientId);
|
||||
if (clientId.isEmpty())
|
||||
clientId = "slide";
|
||||
|
||||
client = mosquitto_new(clientId.toUtf8().constData(), true, this);
|
||||
if (!client)
|
||||
{
|
||||
Log("MQTT: failed to create client.");
|
||||
return;
|
||||
}
|
||||
|
||||
mosquitto_connect_callback_set(client, &MqttController::HandleConnect);
|
||||
mosquitto_message_callback_set(client, &MqttController::HandleMessage);
|
||||
|
||||
if (!config.username.empty())
|
||||
{
|
||||
mosquitto_username_pw_set(client, config.username.c_str(),
|
||||
config.password.empty() ? nullptr : config.password.c_str());
|
||||
}
|
||||
|
||||
mosquitto_reconnect_delay_set(client, 2, 30, true);
|
||||
|
||||
int rc = mosquitto_connect_async(client, config.host.c_str(), config.port, config.keepAlive);
|
||||
if (rc != MOSQ_ERR_SUCCESS)
|
||||
{
|
||||
Log("MQTT connect failed: ", mosquitto_strerror(rc));
|
||||
return;
|
||||
}
|
||||
|
||||
rc = mosquitto_loop_start(client);
|
||||
if (rc != MOSQ_ERR_SUCCESS)
|
||||
{
|
||||
Log("MQTT loop start failed: ", mosquitto_strerror(rc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MqttController::HandleConnect(struct mosquitto *mosq, void *userdata, int rc)
|
||||
{
|
||||
auto *self = static_cast<MqttController *>(userdata);
|
||||
if (!self || !mosq)
|
||||
return;
|
||||
if (rc != 0)
|
||||
{
|
||||
Log("MQTT connect error: ", mosquitto_strerror(rc));
|
||||
return;
|
||||
}
|
||||
self->connected = true;
|
||||
self->subscribe();
|
||||
}
|
||||
|
||||
void MqttController::subscribe()
|
||||
{
|
||||
if (!client || !connected)
|
||||
return;
|
||||
int rc = mosquitto_subscribe(client, nullptr, config.topic.c_str(), config.qos);
|
||||
if (rc != MOSQ_ERR_SUCCESS)
|
||||
{
|
||||
Log("MQTT subscribe failed: ", mosquitto_strerror(rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("MQTT subscribed to ", config.topic);
|
||||
}
|
||||
}
|
||||
|
||||
void MqttController::HandleMessage(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
|
||||
{
|
||||
Q_UNUSED(mosq);
|
||||
auto *self = static_cast<MqttController *>(userdata);
|
||||
if (!self || !message || !message->payload)
|
||||
return;
|
||||
|
||||
QString payload = QString::fromUtf8(static_cast<const char *>(message->payload), message->payloadlen);
|
||||
QMetaObject::invokeMethod(self, "handleCommand", Qt::QueuedConnection, Q_ARG(QString, payload));
|
||||
}
|
||||
|
||||
void MqttController::handleCommand(const QString &payload)
|
||||
{
|
||||
QString cmd = payload.trimmed().toLower();
|
||||
if (cmd.isEmpty())
|
||||
return;
|
||||
|
||||
if (cmd == "play" || cmd == "resume")
|
||||
{
|
||||
emit play();
|
||||
return;
|
||||
}
|
||||
if (cmd == "pause")
|
||||
{
|
||||
emit pause();
|
||||
return;
|
||||
}
|
||||
if (cmd == "next" || cmd == "skip" || cmd == "next-image")
|
||||
{
|
||||
emit nextImage();
|
||||
return;
|
||||
}
|
||||
if (cmd == "next-folder" || cmd == "folder-next" || cmd == "skip-folder")
|
||||
{
|
||||
emit nextFolder();
|
||||
return;
|
||||
}
|
||||
if (cmd == "restart" || cmd == "reset")
|
||||
{
|
||||
emit restart();
|
||||
return;
|
||||
}
|
||||
|
||||
Log("MQTT unknown command: ", cmd.toStdString());
|
||||
}
|
||||
Reference in New Issue
Block a user