164 lines
3.6 KiB
C++
164 lines
3.6 KiB
C++
#include "mqttitem.h"
|
|
|
|
#include <QJsonObject>
|
|
#include <QJsonDocument>
|
|
#include <QtMqtt/QMqttClient>
|
|
|
|
#include "mqttclient.h"
|
|
|
|
MqttItem::MqttItem(QString name, uint8_t value, QObject *parent)
|
|
: Item(0, name, value, parent),
|
|
topic_(""),
|
|
valueKey_("state"),
|
|
valueOn_("ON"),
|
|
valueOff_("OFF")
|
|
{
|
|
hashId();
|
|
std::shared_ptr<MqttClient> workClient = client.lock();
|
|
assert(workClient);
|
|
|
|
connect(workClient->getClient().get(), &QMqttClient::stateChanged, this, &MqttItem::onClientStateChanged);
|
|
}
|
|
|
|
MqttItem::~MqttItem()
|
|
{
|
|
qDebug()<<__func__;
|
|
std::shared_ptr<MqttClient> workClient = client.lock();
|
|
if(!workClient || topic_.isEmpty() || !subscription)
|
|
return;
|
|
|
|
workClient->unsubscribe(subscription);
|
|
}
|
|
|
|
void MqttItem::onClientStateChanged(QMqttClient::ClientState state)
|
|
{
|
|
if(state == QMqttClient::Connected)
|
|
refreshSubscription();
|
|
}
|
|
|
|
void MqttItem::refreshSubscription()
|
|
{
|
|
std::shared_ptr<MqttClient> workClient = client.lock();
|
|
if(!workClient || topic_.isEmpty())
|
|
return;
|
|
|
|
if(workClient->getClient()->state() != QMqttClient::Connected)
|
|
return;
|
|
|
|
if(subscription)
|
|
{
|
|
disconnect(subscription->subscription, &QMqttSubscription::messageReceived, this, &MqttItem::onMessageReceived);
|
|
workClient->unsubscribe(subscription);
|
|
}
|
|
|
|
subscription = workClient->subscribe(workClient->getBaseTopic() + "/" + getTopic());
|
|
connect(subscription->subscription, &QMqttSubscription::messageReceived, this, &MqttItem::onMessageReceived);
|
|
}
|
|
|
|
void MqttItem::onMessageReceived(const QMqttMessage& message)
|
|
{
|
|
QJsonDocument doc = QJsonDocument::fromJson(message.payload());
|
|
if(doc.isObject())
|
|
{
|
|
QJsonObject obj = doc.object();
|
|
if(obj.contains(getValueKey()))
|
|
{
|
|
QString value = obj[getValueKey()].toString();
|
|
ItemUpdateRequest req = createValueUpdateRequest(ITEM_UPDATE_BACKEND);
|
|
req.changes.value = true;
|
|
if(value == getValueOn())
|
|
req.payload.setValueData(true);
|
|
else
|
|
req.payload.setValueData(false);
|
|
requestUpdate(req);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MqttItem::hashId()
|
|
{
|
|
QString hashString = topic_ + "/" + valueKey_;
|
|
itemId_ = qHash(hashString.toLatin1());
|
|
}
|
|
|
|
void MqttItem::setTopic(const QString& topic)
|
|
{
|
|
topic_ = topic;
|
|
hashId();
|
|
refreshSubscription();
|
|
}
|
|
|
|
void MqttItem::setValueKey(const QString& valueKey)
|
|
{
|
|
valueKey_ = valueKey;
|
|
hashId();
|
|
}
|
|
|
|
void MqttItem::setValueOn(const QString& valueOn)
|
|
{
|
|
valueOn_ = valueOn;
|
|
}
|
|
|
|
void MqttItem::setValueOff(const QString& valueOff)
|
|
{
|
|
valueOff_ = valueOff;
|
|
}
|
|
|
|
QString MqttItem::getTopic() const
|
|
{
|
|
return topic_;
|
|
}
|
|
|
|
QString MqttItem::getValueKey() const
|
|
{
|
|
return valueKey_;
|
|
}
|
|
|
|
QString MqttItem::getValueOn() const
|
|
{
|
|
return valueOn_;
|
|
}
|
|
|
|
QString MqttItem::getValueOff() const
|
|
{
|
|
return valueOff_;
|
|
}
|
|
|
|
void MqttItem::store(QJsonObject& json)
|
|
{
|
|
Item::store(json);
|
|
json["Type"] = "Mqtt";
|
|
json["Topic"] = topic_;
|
|
json["ValueKey"] = valueKey_;
|
|
json["ValueOn"] = valueOn_;
|
|
json["ValueOff"] = valueOff_;
|
|
}
|
|
|
|
void MqttItem::load(const QJsonObject& json, const bool preserve)
|
|
{
|
|
Item::load(json, preserve);
|
|
topic_ = json["Topic"].toString();
|
|
valueKey_ = json["ValueKey"].toString("state");
|
|
valueOn_ = json["ValueOn"].toString("ON");
|
|
valueOff_ = json["ValueOff"].toString("OFF");
|
|
hashId();
|
|
refreshSubscription();
|
|
}
|
|
|
|
void MqttItem::enactValue(uint8_t value)
|
|
{
|
|
std::shared_ptr<MqttClient> workClient = client.lock();
|
|
if(!workClient || topic_.isEmpty())
|
|
return;
|
|
|
|
QString fullTopic = workClient->getBaseTopic() + "/" + topic_ + "/set";
|
|
QJsonObject payload;
|
|
|
|
payload[valueKey_] = value ? valueOn_ : valueOff_;
|
|
|
|
QJsonDocument doc(payload);
|
|
QByteArray data = doc.toJson(QJsonDocument::Compact);
|
|
|
|
qDebug() << "MqttItem publishing to" << fullTopic << ":" << data;
|
|
workClient->getClient()->publish(fullTopic, data);
|
|
}
|