diff --git a/qt-openzwave/source/qtozwnodemodel.cpp b/qt-openzwave/source/qtozwnodemodel.cpp index 71f1863..9de00ea 100644 --- a/qt-openzwave/source/qtozwnodemodel.cpp +++ b/qt-openzwave/source/qtozwnodemodel.cpp @@ -142,7 +142,7 @@ QVariant QTOZW_Nodes::headerData(int section, Qt::Orientation orientation, int r return tr("Node Version"); case NodeGroups: - return tr("Node Groups Supported"); + return tr("Node Groups Supported"); case NodeFlags: return tr("Node Flags"); diff --git a/qt-ozwdaemon/main.cpp b/qt-ozwdaemon/main.cpp index f8f0897..cc4fd17 100644 --- a/qt-ozwdaemon/main.cpp +++ b/qt-ozwdaemon/main.cpp @@ -2,12 +2,14 @@ #include #include #include "qtozwdaemon.h" +#include "mqttpublisher.h" +#include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); - QCoreApplication::setApplicationName("qt-ozwdaemon"); - QCoreApplication::setApplicationVersion("1.0"); + QCoreApplication::setApplicationName("ozwdaemon"); + QCoreApplication::setApplicationVersion("0.1"); QCoreApplication::setOrganizationName("OpenZWave"); QCoreApplication::setOrganizationDomain("openzwave.com"); @@ -36,6 +38,22 @@ int main(int argc, char *argv[]) parser.addOption(userDir); + QCommandLineOption MQTTServer(QStringList() << "mqtt-server", + "MQTT Server Hostname/IP Address", + "IP/Hostname" + ); + + parser.addOption(MQTTServer); + + QCommandLineOption MQTTPort(QStringList() << "mqtt-port", + "MQTT Server Port", + "Port" + ); + + + parser.addOption(MQTTPort); + + parser.process(a); if (!parser.isSet(serialPort)) { fputs(qPrintable("Serial Port is Required\n"), stderr); @@ -43,7 +61,13 @@ int main(int argc, char *argv[]) fputs(qPrintable(parser.helpText()), stderr); exit(-1); } - + QSettings settings; + if (parser.isSet(MQTTServer)) { + settings.setValue("MQTTServer", parser.value(MQTTServer)); + } + if (parser.isSet(MQTTPort)) { + settings.setValue("MQTTPort", parser.value(MQTTPort).toInt()); + } #if 1 QLoggingCategory::setFilterRules("qt.remoteobjects.debug=true\n" @@ -55,7 +79,69 @@ int main(int argc, char *argv[]) #else QLoggingCategory::setFilterRules("default.debug=true"); #endif + + QStringList PossibleDBPaths; + if (parser.isSet(configDir)) + PossibleDBPaths << parser.value(configDir); + PossibleDBPaths << "./config/"; + PossibleDBPaths << settings.value("openzwave/ConfigPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); + PossibleDBPaths << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); + + QString path, dbPath, userPath; + foreach(path, PossibleDBPaths) { + qDebug() << "Checking " << QFileInfo(QDir::toNativeSeparators(path+"/config/manufacturer_specific.xml")).absoluteFilePath() << " for manufacturer_specific.xml"; + if (QFileInfo(QDir::toNativeSeparators(path+"/config/manufacturer_specific.xml")).exists()) { + dbPath = QFileInfo(QDir::toNativeSeparators(path+"/config/manufacturer_specific.xml")).absoluteFilePath(); + break; + } + qDebug() << "Checking " << QFileInfo(QDir::toNativeSeparators(path+"../config/manufacturer_specific.xml")).absoluteFilePath() << " for manufacturer_specific.xml"; + if (QFile(QDir::toNativeSeparators(path+"/../config/manufacturer_specific.xml")).exists()) { + dbPath = QFileInfo(QDir::toNativeSeparators(path+"/../config/manufacturer_specific.xml")).absoluteFilePath(); + break; + } + } + PossibleDBPaths.clear(); + if (parser.isSet(userDir)) + PossibleDBPaths << parser.value(userDir); + PossibleDBPaths << "./config/"; + PossibleDBPaths << settings.value("openzwave/UserPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); + PossibleDBPaths << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); + + foreach(path, PossibleDBPaths) { + qDebug() << "Checking " << QFileInfo(QDir::toNativeSeparators(path+"/config/Options.xml")).absoluteFilePath() << " for options.xml"; + if (QFileInfo(QDir::toNativeSeparators(path+"/config/options.xml")).exists()) { + userPath = QFileInfo(QDir::toNativeSeparators(path+"/config/options.xml")).absoluteFilePath(); + break; + } + qDebug() << "Checking " << QFileInfo(QDir::toNativeSeparators(path+"/../config/options.xml")).absoluteFilePath() << " for options.xml"; + if (QFile(QDir::toNativeSeparators(path+"/../config/options.xml")).exists()) { + userPath = QFileInfo(QDir::toNativeSeparators(path+"/../config/options.xml")).absoluteFilePath(); + break; + } + } + +// if (userPath.isEmpty()) { +// fputs(qPrintable("userPath is Not Set or Missing\n"), stderr); +// exit(-1); +// } + if (dbPath.isEmpty()) { + copyConfigDatabase(QFileInfo("./").absoluteFilePath().append("/")); + dbPath = "./config/"; + userPath = "./config/"; + } + qDebug() << "DBPath: " << dbPath; + qDebug() << "userPath: " << userPath; + + + QTOZWOptions options(QTOZWOptions::Local); + options.setUserPath(userPath); + options.setConfigPath(dbPath); + + + qtozwdaemon daemon; + mqttpublisher mqttpublisher; + mqttpublisher.setOZWDaemon(&daemon); daemon.setSerialPort(parser.value(serialPort)); daemon.startOZW(); return a.exec(); diff --git a/qt-ozwdaemon/mqttpublisher.cpp b/qt-ozwdaemon/mqttpublisher.cpp new file mode 100644 index 0000000..ddf5f6e --- /dev/null +++ b/qt-ozwdaemon/mqttpublisher.cpp @@ -0,0 +1,383 @@ +#include + +#include "mqttpublisher.h" + +mqttNodeModel::mqttNodeModel(QObject *parent) +{ + +} + +QVariant mqttNodeModel::getNodeData(quint8 node, NodeColumns col) { + int row = this->getNodeRow(node); + return this->data(this->index(row, col), Qt::DisplayRole); +} + +bool mqttNodeModel::populateJsonObject(QJsonObject *jsonobject, quint8 node, QTOZWManager *mgr) { + for (int i = 0; i < this->columnCount(QModelIndex()); i++) { + QVariant data = this->getNodeData(node, static_cast(i)); + switch (static_cast(i)) { + case NodeColumns::NodeFlags: { + QBitArray flag = data.toBitArray(); + QMetaEnum metaEnum = QMetaEnum::fromType(); + for (int j = 0; j < nodeFlags::flagCount; j++) { + jsonobject->insert(metaEnum.valueToKey(j), flag.at(j)); + } + break; + } + default: { + QMetaEnum metaEnum = QMetaEnum::fromType(); + if (data.type() == QMetaType::QString) { + jsonobject->insert(metaEnum.valueToKey(i), data.toString()); + } else if (data.type() == QMetaType::Bool) { + jsonobject->insert(metaEnum.valueToKey(i), data.toBool()); + } else if (data.type() == QMetaType::Int) { + jsonobject->insert(metaEnum.valueToKey(i), data.toInt()); + } else if (data.type() == QMetaType::UInt) { + jsonobject->insert(metaEnum.valueToKey(i), data.toInt()); + } else { + qWarning() << "Can't Convert " << data.type() << "(" << metaEnum.valueToKey(i) << ") to store in JsonObject: " << node; + } + break; + } + } + + } + /* MetaData */ + QJsonObject metadata = jsonobject->value("MetaData").toObject(); + QMetaEnum metaEnum = QMetaEnum::fromType(); + if (metadata.empty()) { + for (int i = 0; i < QTOZWManagerSource::Identifier; i++) { + metadata.insert(metaEnum.valueToKey(i), mgr->GetMetaData(node, static_cast(i))); + } + metadata.insert("ProductPicBase64", QString(mgr->GetMetaDataProductPic(node).toBase64())); + jsonobject->insert("MetaData", metadata); + } + qDebug() << jsonobject; + return true; +} + +mqttValueIDModel::mqttValueIDModel(QObject *parent) { + +} +QVariant mqttValueIDModel::getValueData(quint64 vidKey, ValueIdColumns col) { + int row = this->getValueRow(vidKey); + return this->data(this->index(row, col), Qt::DisplayRole); +} + + +bool mqttValueIDModel::populateJsonObject(QJsonObject *jsonobject, quint64 vidKey, QTOZWManager *mgr) { + for (int i = 0; i < ValueIdColumns::ValueIdCount; i++) { + QVariant data = this->getValueData(vidKey, static_cast(i)); + switch (static_cast(i)) { + case ValueFlags: { + QBitArray flag = data.toBitArray(); + QMetaEnum metaEnum = QMetaEnum::fromType(); + for (int j = 0; j < ValueIDFlags::FlagCount; j++) { + jsonobject->insert(metaEnum.valueToKey(j), flag.at(j)); + } + break; + } + case Value: { + jsonobject->insert("Value", this->encodeValue(vidKey)); + break; + } + default: { + QMetaEnum metaEnum = QMetaEnum::fromType(); + if (data.type() == QMetaType::QString) { + jsonobject->insert(metaEnum.valueToKey(i), data.toString()); + } else if (data.type() == QMetaType::Bool) { + jsonobject->insert(metaEnum.valueToKey(i), data.toBool()); + } else if (data.type() == QMetaType::Int) { + jsonobject->insert(metaEnum.valueToKey(i), data.toInt()); + } else if (data.type() == QMetaType::UInt) { + jsonobject->insert(metaEnum.valueToKey(i), data.toInt()); + } else if (data.type() == QMetaType::Float) { + jsonobject->insert(metaEnum.valueToKey(i), data.toDouble()); + } else if (data.type() == QMetaType::ULongLong) { + jsonobject->insert(metaEnum.valueToKey(i), static_cast(data.toULongLong())); + } else { + qWarning() << "Can't Convert " << data.type() << "(" << metaEnum.valueToKey(i) << ") to store in JsonObject: " << vidKey; + } + break; + } + + } + } + + + qDebug() << jsonobject; + return true; +} + +QJsonValue mqttValueIDModel::encodeValue(quint64 vidKey) { + QJsonValue value; + QVariant data = this->getValueData(vidKey, mqttValueIDModel::ValueIdColumns::Value); + if (data.type() == QMetaType::QString) { + value = data.toString(); + } else if (data.type() == QMetaType::Bool) { + value = data.toBool(); + } else if (data.type() == QMetaType::Int) { + value = data.toInt(); + } else if (data.type() == QMetaType::UInt) { + value = data.toInt(); + } else if (data.type() == QMetaType::Float) { + value = data.toDouble(); + } else if (data.type() == QMetaType::ULongLong) { + value = static_cast(data.toULongLong()); + } else { + qWarning() << "Can't Convert " << data.type() << " to store in JsonObject: " << vidKey; + } + return value; +} + + + +mqttpublisher::mqttpublisher(QObject *parent) : QObject(parent) +{ + + this->m_client = new QMqttClient(this); + this->m_client->setHostname(settings.value("MQTTServer", "127.0.0.1").toString()); + this->m_client->setPort(static_cast(settings.value("MQTTPort", 1883).toInt())); + + connect(this->m_client, &QMqttClient::stateChanged, this, &mqttpublisher::updateLogStateChange); + connect(this->m_client, &QMqttClient::disconnected, this, &mqttpublisher::brokerDisconnected); + + connect(this->m_client, &QMqttClient::messageReceived, this, &mqttpublisher::handleMessage); + connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() { + const QString content = QDateTime::currentDateTime().toString() + + QLatin1String(" PingResponse") + + QLatin1Char('\n'); + qDebug() << content; + }); + + this->m_client->setWillTopic(getTopic(MQTT_OZW_STATUS_TOPIC)); + QJsonObject willMsg; + willMsg["Status"] = "Offline"; + this->m_client->setWillMessage(QJsonDocument(willMsg).toJson()); + this->m_client->setWillRetain(true); + +} + +QString mqttpublisher::getTopic(QString topic) { + return QString(MQTT_OZW_TOP_TOPIC).arg(settings.value("Instance", 1).toInt()).append(topic); +} + +QString mqttpublisher::getNodeTopic(QString topic, quint8 node) { + QString t(MQTT_OZW_TOP_TOPIC); + t = t.arg(settings.value("Instance", 1).toInt()); + t.append(topic.arg(static_cast(node))); + return t; +} +QString mqttpublisher::getValueTopic(QString topic, quint8 node, quint64 vid) { + QString t(MQTT_OZW_TOP_TOPIC); + t = t.arg(settings.value("Instance", 1).toInt()); + t.append(topic.arg(static_cast(node)).arg(static_cast(vid))); + return t; +} + + +void mqttpublisher::setOZWDaemon(qtozwdaemon *ozwdaemon) { + this->m_qtozwdeamon = ozwdaemon; + + QTOZWManager *manager = this->m_qtozwdeamon->getManager(); + + this->m_nodeModel = static_cast(manager->getNodeModel()); + this->m_valueModel = static_cast(manager->getValueModel()); + + connect(manager, &QTOZWManager::ready, this, &mqttpublisher::ready); + connect(manager, &QTOZWManager::valueAdded, this, &mqttpublisher::valueAdded); + connect(manager, &QTOZWManager::valueChanged, this, &mqttpublisher::valueChanged); + connect(manager, &QTOZWManager::valueRemoved, this, &mqttpublisher::valueRemoved); + connect(manager, &QTOZWManager::valueRefreshed, this, &mqttpublisher::valueRefreshed); + connect(manager, &QTOZWManager::nodeNew, this, &mqttpublisher::nodeNew); + connect(manager, &QTOZWManager::nodeAdded, this, &mqttpublisher::nodeAdded); + connect(manager, &QTOZWManager::nodeEvent, this, &mqttpublisher::nodeEvent); + connect(manager, &QTOZWManager::nodeReset, this, &mqttpublisher::nodeReset); + connect(manager, &QTOZWManager::nodeNaming, this, &mqttpublisher::nodeNaming); + connect(manager, &QTOZWManager::nodeRemoved, this, &mqttpublisher::nodeRemoved); + connect(manager, &QTOZWManager::nodeProtocolInfo, this, &mqttpublisher::nodeProtocolInfo); + connect(manager, &QTOZWManager::nodeEssentialNodeQueriesComplete, this, &mqttpublisher::nodeEssentialNodeQueriesComplete); + connect(manager, &QTOZWManager::nodeQueriesComplete, this, &mqttpublisher::nodeQueriesComplete); + connect(manager, &QTOZWManager::driverReady, this, &mqttpublisher::driverReady); + connect(manager, &QTOZWManager::driverReset, this, &mqttpublisher::driverReset); + connect(manager, &QTOZWManager::driverFailed, this, &mqttpublisher::driverFailed); + connect(manager, &QTOZWManager::driverRemoved, this, &mqttpublisher::driverRemoved); + connect(manager, &QTOZWManager::driverAllNodesQueried, this, &mqttpublisher::driverAllNodesQueried); + connect(manager, &QTOZWManager::driverAwakeNodesQueried, this, &mqttpublisher::driverAwakeNodesQueried); + connect(manager, &QTOZWManager::driverAllNodesQueriedSomeDead, this, &mqttpublisher::driverAllNodesQueriedSomeDead); + connect(manager, &QTOZWManager::controllerCommand, this, &mqttpublisher::controllerCommand); + connect(manager, &QTOZWManager::manufacturerSpecificDBReady, this, &mqttpublisher::manufacturerSpecificDBReady); + connect(manager, &QTOZWManager::starting, this, &mqttpublisher::starting); + connect(manager, &QTOZWManager::started, this, &mqttpublisher::started); + connect(manager, &QTOZWManager::stopped, this, &mqttpublisher::stopped); + + this->m_client->connectToHost(); +} + +void mqttpublisher::updateLogStateChange() +{ + const QString content = QDateTime::currentDateTime().toString() + + QLatin1String(": State Change: " ) + + QString::number(m_client->state()); + qDebug() << content; + if (this->m_client->state() == QMqttClient::ClientState::Connected) { + this->m_client->subscribe(QMqttTopicFilter("/OpenZWave/commands")); + } + +} + +void mqttpublisher::brokerDisconnected() +{ + qDebug() << "Disconnnected"; +} + +void mqttpublisher::handleMessage(const QByteArray &message, const QMqttTopicName &topic) { + qDebug() << "Received: " << topic.name() << ":" << message; +} + + +bool mqttpublisher::sendStatusUpdate() { + qDebug() << QJsonDocument(this->m_ozwstatus).toJson(); + this->m_client->publish(QMqttTopicName(getTopic(MQTT_OZW_STATUS_TOPIC)), QJsonDocument(this->m_ozwstatus).toJson(), 0, true); + return true; +} + +bool mqttpublisher::sendNodeUpdate(quint8 node) { + qDebug() << this->m_nodeModel->getNodeData(node, QTOZW_Nodes::NodeProductName); + this->m_client->publish(QMqttTopicName(getNodeTopic(MQTT_OZW_NODE_TOPIC, node)), QJsonDocument(this->m_nodes[node]).toJson(), 0, true); + return true; +} + +bool mqttpublisher::sendValueUpdate(quint64 vidKey) { + quint8 node = this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::Node).value(); + if (node == 0) + return false; + this->m_client->publish(QMqttTopicName(getValueTopic(MQTT_OZW_VID_TOPIC, node, vidKey)), QJsonDocument(this->m_values[vidKey]).toJson(), 0, true); + return true; +} + + +void mqttpublisher::ready() { + this->m_ozwstatus["Status"] = "Ready"; + this->sendStatusUpdate(); +} +void mqttpublisher::valueAdded(quint64 vidKey) { + this->m_valueModel->populateJsonObject(&this->m_values[vidKey], vidKey, this->m_qtozwdeamon->getManager()); + this->m_values[vidKey]["Event"] = "valueAdded"; + this->sendValueUpdate(vidKey); +} +void mqttpublisher::valueRemoved(quint64 vidKey) { + this->m_values[vidKey]["Event"] = "valueRemoved"; + this->sendValueUpdate(vidKey); + +} +void mqttpublisher::valueChanged(quint64 vidKey) { + this->m_values[vidKey]["Event"] = "valueChanged"; + this->m_values[vidKey]["Value"] = this->m_valueModel->encodeValue(vidKey); + this->sendValueUpdate(vidKey); + +} +void mqttpublisher::valueRefreshed(quint64 vidKey) { + this->m_values[vidKey]["Event"] = "valueRefreshed"; + this->m_values[vidKey]["Value"] = this->m_valueModel->encodeValue(vidKey); + this->sendValueUpdate(vidKey); +} +void mqttpublisher::nodeNew(quint8 node) { + this->m_nodeModel->populateJsonObject(&this->m_nodes[node], node, this->m_qtozwdeamon->getManager()); + this->m_nodes[node]["Event"] = "nodeNew"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeAdded(quint8 node) { + this->m_nodeModel->populateJsonObject(&this->m_nodes[node], node, this->m_qtozwdeamon->getManager()); + this->m_nodes[node]["Event"] = "nodeAdded"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeRemoved(quint8 node) { + this->m_nodes[node]["Event"] = "nodeRemoved"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeReset(quint8 node) { + this->m_nodes[node]["Event"] = "nodeReset"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeNaming(quint8 node) { + this->m_nodes[node]["Event"] = "nodeNaming"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeEvent(quint8 node, quint8 event) { + this->m_nodes[node]["Event"] = "nodeEvent"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeProtocolInfo(quint8 node) { + this->m_nodeModel->populateJsonObject(&this->m_nodes[node], node, this->m_qtozwdeamon->getManager()); + this->m_nodes[node]["Event"] = "nodeProtocolInfo"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeEssentialNodeQueriesComplete(quint8 node) { + this->m_nodeModel->populateJsonObject(&this->m_nodes[node], node, this->m_qtozwdeamon->getManager()); + this->m_nodes[node]["Event"] = "nodeEssentialNodeQueriesComplete"; + this->sendNodeUpdate(node); +} +void mqttpublisher::nodeQueriesComplete(quint8 node) { + this->m_nodeModel->populateJsonObject(&this->m_nodes[node], node, this->m_qtozwdeamon->getManager()); + this->m_nodes[node]["Event"] = "nodeQueriesComplete"; + this->sendNodeUpdate(node); +} +void mqttpublisher::driverReady(quint32 homeID) { + this->m_ozwstatus["Status"] = "driverReady"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +void mqttpublisher::driverFailed(quint32 homeID) { + this->m_ozwstatus["Status"] = "driverFailed"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +void mqttpublisher::driverReset(quint32 homeID) { + this->m_ozwstatus["Status"] = "driverReset"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +void mqttpublisher::driverRemoved(quint32 homeID) { + this->m_ozwstatus["Status"] = "driverRemoved"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +void mqttpublisher::driverAllNodesQueriedSomeDead() { + this->m_ozwstatus["Status"] = "driverAllNodesQueriedSomeDead"; + this->sendStatusUpdate(); +} +void mqttpublisher::driverAllNodesQueried() { + this->m_ozwstatus["Status"] = "driverAllNodesQueried"; + this->sendStatusUpdate(); +} +void mqttpublisher::driverAwakeNodesQueried() { + this->m_ozwstatus["Status"] = "driverAwakeNodesQueried"; + this->sendStatusUpdate(); +} +void mqttpublisher::controllerCommand(quint8 command) { + +} +//void ozwNotification(OpenZWave::Notification::NotificationCode event); +//void ozwUserAlert(OpenZWave::Notification::UserAlertNotification event); +void mqttpublisher::manufacturerSpecificDBReady() { + +} + +void mqttpublisher::starting() { + this->m_ozwstatus["Status"] = "starting"; + qDebug() << QJsonDocument(this->m_ozwstatus).toJson(); + this->sendStatusUpdate(); +} +void mqttpublisher::started(quint32 homeID) { + this->m_ozwstatus["Status"] = "started"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +void mqttpublisher::stopped(quint32 homeID) { + this->m_ozwstatus["Status"] = "stopped"; + this->m_ozwstatus["homeID"] = QJsonValue(static_cast(homeID)); + this->sendStatusUpdate(); +} +//void error(QTOZWErrorCodes errorcode); + diff --git a/qt-ozwdaemon/mqttpublisher.h b/qt-ozwdaemon/mqttpublisher.h new file mode 100644 index 0000000..2f68013 --- /dev/null +++ b/qt-ozwdaemon/mqttpublisher.h @@ -0,0 +1,104 @@ +#ifndef MQTTPUBLISHER_H +#define MQTTPUBLISHER_H + +#include + +#include +#include +#include + +#include "qtozwdaemon.h" + + +#define MQTT_OZW_TOP_TOPIC "/OpenZWave/%1/" +#define MQTT_OZW_STATUS_TOPIC "status/" +#define MQTT_OZW_NODE_TOPIC "node/%1/" +#define MQTT_OZW_VID_TOPIC "node/%1/%2/" + +class mqttNodeModel : public QTOZW_Nodes { + Q_OBJECT +public: + explicit mqttNodeModel(QObject *parent = nullptr); + + QVariant getNodeData(quint8, NodeColumns); + bool populateJsonObject(QJsonObject *, quint8, QTOZWManager *); +}; + +class mqttValueIDModel : public QTOZW_ValueIds { + Q_OBJECT +public: + explicit mqttValueIDModel(QObject *parent = nullptr); + QVariant getValueData(quint64, ValueIdColumns); + bool populateJsonObject(QJsonObject *, quint64, QTOZWManager *); + QJsonValue encodeValue(quint64); +}; + +class mqttpublisher : public QObject +{ + Q_OBJECT +public: + explicit mqttpublisher(QObject *parent = nullptr); + void setOZWDaemon(qtozwdaemon *ozwdaemon); +signals: + +public slots: + void ready(); + void valueAdded(quint64 vidKey); + void valueRemoved(quint64 vidKey); + void valueChanged(quint64 vidKey); + void valueRefreshed(quint64 vidKey); + void nodeNew(quint8 node); + void nodeAdded(quint8 node); + void nodeRemoved(quint8 node); + void nodeReset(quint8 node); + void nodeNaming(quint8 node); + void nodeEvent(quint8 node, quint8 event); + void nodeProtocolInfo(quint8 node); + void nodeEssentialNodeQueriesComplete(quint8 node); + void nodeQueriesComplete(quint8 node); + void driverReady(quint32 homeID); + void driverFailed(quint32 homeID); + void driverReset(quint32 homeID); + void driverRemoved(quint32 homeID); + void driverAllNodesQueriedSomeDead(); + void driverAllNodesQueried(); + void driverAwakeNodesQueried(); + void controllerCommand(quint8 command); +// void ozwNotification(OpenZWave::Notification::NotificationCode event); +// void ozwUserAlert(OpenZWave::Notification::UserAlertNotification event); + void manufacturerSpecificDBReady(); + + void starting(); + void started(quint32 homeID); + void stopped(quint32 homeID); +// void error(QTOZWErrorCodes errorcode); + + + + +private slots: + void updateLogStateChange(); + void brokerDisconnected(); + void handleMessage(const QByteArray &message, const QMqttTopicName &topic = QMqttTopicName()); + +private: + + QString getTopic(QString); + QString getNodeTopic(QString, quint8); + QString getValueTopic(QString, quint8, quint64); + bool sendStatusUpdate(); + bool sendNodeUpdate(quint8); + bool sendValueUpdate(quint64); + + QJsonObject m_ozwstatus; + QMap m_nodes; + mqttNodeModel *m_nodeModel; + QMap m_values; + mqttValueIDModel *m_valueModel; + + QMqttClient *m_client; + qtozwdaemon *m_qtozwdeamon; + QSettings settings; +}; + +#endif // MQTTPUBLISHER_H diff --git a/qt-ozwdaemon/qt-ozwdaemon.pro b/qt-ozwdaemon/qt-ozwdaemon.pro index 846739f..de5b503 100644 --- a/qt-ozwdaemon/qt-ozwdaemon.pro +++ b/qt-ozwdaemon/qt-ozwdaemon.pro @@ -20,6 +20,7 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ main.cpp \ + mqttpublisher.cpp \ qtozwdaemon.cpp # Default rules for deployment. @@ -28,6 +29,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ + mqttpublisher.h \ qtozwdaemon.h include(../qt-openzwave.pri) @@ -35,7 +37,8 @@ include(../qt-openzwave.pri) INCLUDEPATH += ../qt-openzwave/include/ unix { - LIBS += -lresolv -L../qt-openzwave/ -lqt-openzwave + LIBS += -lresolv -L../qt-openzwave/ -lqt-openzwave -L../qt-openzwavedatabase/ -lqt-openzwavedatabase + INCLUDEPATH += ../qt-openzwavedatabase/include/ } win32 { LIBS += -lDnsapi -L../qt-openzwave/$$BUILDTYPE/ -lqt-openzwave1 diff --git a/qt-ozwdaemon/qtozwdaemon.cpp b/qt-ozwdaemon/qtozwdaemon.cpp index 8319759..6af1949 100644 --- a/qt-ozwdaemon/qtozwdaemon.cpp +++ b/qt-ozwdaemon/qtozwdaemon.cpp @@ -8,22 +8,6 @@ qtozwdaemon::qtozwdaemon(QObject *parent) : QObject(parent) this->m_qtozwmanager = this->m_openzwave->GetManager(); QObject::connect(this->m_qtozwmanager, &QTOZWManager::ready, this, &qtozwdaemon::QTOZW_Ready); this->m_qtozwmanager->initilizeSource(true); - - this->m_client = new QMqttClient(this); - this->m_client->setHostname("10.51.107.19"); - this->m_client->setPort(1883); - - connect(this->m_client, &QMqttClient::stateChanged, this, &qtozwdaemon::updateLogStateChange); - connect(this->m_client, &QMqttClient::disconnected, this, &qtozwdaemon::brokerDisconnected); - - connect(this->m_client, &QMqttClient::messageReceived, this, &qtozwdaemon::handleMessage); - connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() { - const QString content = QDateTime::currentDateTime().toString() - + QLatin1String(" PingResponse") - + QLatin1Char('\n'); - qDebug() << content; - }); - this->m_client->connectToHost(); } void qtozwdaemon::QTOZW_Ready() { @@ -34,27 +18,10 @@ void qtozwdaemon::startOZW() { qWarning() << "Serial Port is not Set"; return; } - //this->m_qtozwmanager->open(this->getSerialPort()); + this->m_qtozwmanager->open(this->getSerialPort()); } -void qtozwdaemon::updateLogStateChange() -{ - const QString content = QDateTime::currentDateTime().toString() - + QLatin1String(": State Change: " ) - + QString::number(m_client->state()); - qDebug() << content; - if (this->m_client->state() == QMqttClient::ClientState::Connected) { - this->m_client->subscribe(QMqttTopicFilter("/OpenZWave/commands")); - this->m_client->publish(QMqttTopicName("/OpenZWave/commands"), QString("testhaha").toLocal8Bit()); - } - +QTOZWManager *qtozwdaemon::getManager() { + return this->m_qtozwmanager; } -void qtozwdaemon::brokerDisconnected() -{ - qDebug() << "Disconnnected"; -} - -void qtozwdaemon::handleMessage(const QByteArray &message, const QMqttTopicName &topic) { - qDebug() << "Received: " << topic.name() << ":" << message; -} diff --git a/qt-ozwdaemon/qtozwdaemon.h b/qt-ozwdaemon/qtozwdaemon.h index c18b0fa..990e39e 100644 --- a/qt-ozwdaemon/qtozwdaemon.h +++ b/qt-ozwdaemon/qtozwdaemon.h @@ -3,7 +3,7 @@ #include #include -#include + #include #include @@ -16,22 +16,17 @@ public: explicit qtozwdaemon(QObject *parent = nullptr); QString getSerialPort() { return this->m_serialPort; } void setSerialPort(QString serialPort) { this->m_serialPort = serialPort;} - void startOZW(); - + QTOZWManager *getManager(); signals: public slots: void QTOZW_Ready(); - void updateLogStateChange(); - void brokerDisconnected(); - void handleMessage(const QByteArray &message, const QMqttTopicName &topic = QMqttTopicName()); private: QTOpenZwave *m_openzwave; QTOZWManager *m_qtozwmanager; QString m_serialPort; - QMqttClient *m_client; }; #endif // QTOZWDAEMON_H