diff --git a/src/items/mqttitemsource.cpp b/src/items/mqttitemsource.cpp deleted file mode 100644 index eb3c11c..0000000 --- a/src/items/mqttitemsource.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "mqttitemsource.h" - -#include -#include -#include - -MqttItemSource::MqttItemSource(QObject *parent) - : ItemSource(parent) -{ -} - -MqttItemSource::~MqttItemSource() -{ -} - -void MqttItemSource::start(const QJsonObject& settings) -{ - baseTopicName_ = settings["BaseTopic"].toString("zigbee2mqtt"); - - connect(&client_, &QMqttClient::stateChanged, this, &MqttItemSource::onClientStateChanged); - connect(&client_, &QMqttClient::errorChanged, this, &MqttItemSource::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(); - - QJsonArray itemsArray = settings["Items"].toArray(); - - for(QJsonValueRef itemRef : itemsArray) - { - QJsonObject itemObject = itemRef.toObject(); - if(!itemObject.contains("Topic")) - continue; - - MqttItemConfig config; - config.topic = itemObject["Topic"].toString(); - config.name = itemObject.contains("Name") ? itemObject["Name"].toString() : config.topic; - config.valueKey = itemObject["ValueKey"].toString("state"); - config.valueOn = itemObject["ValueOn"].toString("ON"); - config.valueOff = itemObject["ValueOff"].toString("OFF"); - - // Determine value type - QString valueTypeStr = itemObject["ValueType"].toString("bool"); - if(valueTypeStr == "uint") - config.valueType = ITEM_VALUE_UINT; - else - config.valueType = ITEM_VALUE_BOOL; - - config.id = qHash(baseTopicName_ + "/" + config.topic); - - // Create the item - config.item = std::make_shared(config.id, config.name, 0); - config.item->setTopic(config.topic); - config.item->setValueKey(config.valueKey); - config.item->setBaseTopic(baseTopicName_); - config.item->setValueOn(config.valueOn); - config.item->setValueOff(config.valueOff); - config.item->setMqttClient(&client_); - - items_.push_back(config); - } -} - -MqttItemSource::MqttItemConfig* MqttItemSource::findConfig(const QString& topic) -{ - for(MqttItemConfig& config : items_) - { - if(baseTopicName_ + "/" + config.topic == topic) - return &config; - } - return nullptr; -} - -void MqttItemSource::onClientError(QMqttClient::ClientError error) -{ - qWarning() << "MqttItemSource Client error:" << error; -} - -void MqttItemSource::onClientStateChanged(QMqttClient::ClientState state) -{ - if(state == QMqttClient::ClientState::Connected) - { - qInfo() << "MqttItemSource connected to MQTT broker at " << client_.hostname() << client_.port(); - for(MqttItemConfig& config : items_) - { - // Subscribe to state topic to receive updates from devices - QString stateTopic = baseTopicName_ + "/" + config.topic; - qDebug() << "MqttItemSource subscribing to" << stateTopic; - QMqttSubscription* subscription = client_.subscribe(stateTopic); - if(subscription) - { - connect(subscription, &QMqttSubscription::messageReceived, this, &MqttItemSource::onMessageReceived); - } - } - } - else if(state == QMqttClient::ClientState::Disconnected) - { - qWarning() << "MqttItemSource lost connection to MQTT broker"; - } - else if(state == QMqttClient::ClientState::Connecting) - { - qInfo() << "MqttItemSource connecting to MQTT broker at " << client_.hostname() << client_.port(); - } -} - -void MqttItemSource::onMessageReceived(const QMqttMessage& message) -{ - MqttItemConfig* config = findConfig(message.topic().name()); - if(!config) - return; - - QJsonDocument doc = QJsonDocument::fromJson(message.payload()); - if(doc.isObject()) - { - QJsonObject obj = doc.object(); - QString valueKey = config->valueKey; - - if(obj.contains(valueKey)) - { - uint8_t newValue = 0; - - // Handle different value types - if(config->valueType == ITEM_VALUE_UINT) - { - // Numeric value (brightness, etc.) - newValue = obj[valueKey].toInt(0); - } - else - { - // Binary value (state on/off, etc.) - QString value = obj[valueKey].toString(); - if(value == config->valueOn || value == "ON" || value == "true") - newValue = 1; - else if(value == config->valueOff || value == "OFF" || value == "false") - newValue = 0; - } - - // Only update if value changed - if(config->item->getValue() != newValue) - { - ItemUpdateRequest update; - update.type = ITEM_UPDATE_BACKEND; - update.payload = *config->item; - update.payload.setValueData(newValue); - update.changes.value = true; - config->item->requestUpdate(update); - } - } - } -} - -void MqttItemSource::refresh() -{ - std::vector requests; - - for(MqttItemConfig& config : items_) - { - ItemAddRequest request; - request.type = ITEM_UPDATE_BACKEND; - request.payload = config.item; - request.changes = ItemFieldChanges(true); - requests.push_back(request); - } - - gotItems(requests); -} - -void MqttItemSource::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(); - - QJsonArray itemsArray; - for(const MqttItemConfig& config : items_) - { - QJsonObject itemObject; - itemObject["Name"] = config.name; - itemObject["Topic"] = config.topic; - itemObject["ValueKey"] = config.valueKey; - itemObject["ValueOn"] = config.valueOn; - itemObject["ValueOff"] = config.valueOff; - if(config.valueType == ITEM_VALUE_UINT) - itemObject["ValueType"] = "uint"; - else - itemObject["ValueType"] = "bool"; - itemsArray.append(itemObject); - } - json["Items"] = itemsArray; -} - -QMqttClient* MqttItemSource::getClient() -{ - return &client_; -} \ No newline at end of file diff --git a/src/items/mqttitemsource.h b/src/items/mqttitemsource.h deleted file mode 100644 index 080e8a8..0000000 --- a/src/items/mqttitemsource.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MQTTITEMSOURCE_H -#define MQTTITEMSOURCE_H - -#include -#include -#include -#include -#include - -#include "itemsource.h" -#include "mqttitem.h" - -class MqttItemSource : public ItemSource -{ - Q_OBJECT - - QString baseTopicName_; - QMqttClient client_; - -private slots: - void onClientStateChanged(QMqttClient::ClientState state); - void onMessageReceived(const QMqttMessage& message); - void onClientError(QMqttClient::ClientError error); - -public: - explicit MqttItemSource(QObject *parent = nullptr); - virtual ~MqttItemSource() override; - virtual void refresh() override; - void start(const QJsonObject& settings); - void store(QJsonObject& json); - QMqttClient* getClient(); -}; - -#endif // MQTTITEMSOURCE_H \ No newline at end of file