diff --git a/qt-openzwave/include/qt-openzwave/qtozwmanager.h b/qt-openzwave/include/qt-openzwave/qtozwmanager.h index a047b6a..1961f0a 100644 --- a/qt-openzwave/include/qt-openzwave/qtozwmanager.h +++ b/qt-openzwave/include/qt-openzwave/qtozwmanager.h @@ -76,6 +76,7 @@ public: /* OpenZWave::Manager methods */ bool open(QString serialPort); + bool close(); bool refreshNodeInfo(quint8 _node); bool requestNodeState(quint8 _node); bool requestNodeDynamic(quint8 _node); diff --git a/qt-openzwave/include/qt-openzwave/qtozwmanager.rep b/qt-openzwave/include/qt-openzwave/qtozwmanager.rep index 97ab957..e9d1008 100644 --- a/qt-openzwave/include/qt-openzwave/qtozwmanager.rep +++ b/qt-openzwave/include/qt-openzwave/qtozwmanager.rep @@ -93,6 +93,7 @@ class QTOZWManager { SIGNAL(error(QTOZWManagerErrorCodes errorcode)) SLOT(bool open(QString serialPort)) + SLOT(bool close()) SLOT(bool refreshNodeInfo(quint8 _node)) SLOT(bool requestNodeState(quint8 _node)) SLOT(bool requestNodeDynamic(quint8 _node)) diff --git a/qt-openzwave/include/qtozwmanager_p.h b/qt-openzwave/include/qtozwmanager_p.h index 9411e3b..6b1cf27 100644 --- a/qt-openzwave/include/qtozwmanager_p.h +++ b/qt-openzwave/include/qtozwmanager_p.h @@ -69,6 +69,7 @@ public: public Q_SLOTS: bool open(QString serialPort); + bool close(); bool refreshNodeInfo(quint8 _node); bool requestNodeState(quint8 _node); bool requestNodeDynamic(quint8 _node); @@ -164,7 +165,7 @@ private: QVector m_validNodes; QVector m_validValues; QMap > m_associationDefaultsSet; - + QString m_SerialPort; }; diff --git a/qt-openzwave/source/qtozwassociationmodel_p.cpp b/qt-openzwave/source/qtozwassociationmodel_p.cpp index 399b630..a9578ec 100644 --- a/qt-openzwave/source/qtozwassociationmodel_p.cpp +++ b/qt-openzwave/source/qtozwassociationmodel_p.cpp @@ -94,17 +94,15 @@ void QTOZW_Associations_internal::setGroupFlags(quint8 _nodeID, quint8 _groupIDX }; void QTOZW_Associations_internal::delNode(quint8 _nodeID) { - for (int i = 0; i <= rowCount(QModelIndex()); i++) { - if (this->m_associationData[i][associationColumns::NodeID] == _nodeID) { - qCDebug(associationModel) << "Removing Node " << this->m_associationData[i][associationColumns::NodeID] << i; - this->beginRemoveRows(QModelIndex(), i, i); - this->m_associationData.remove(i); - for (int j = i+1; i <= rowCount(QModelIndex()); j++) { - this->m_associationData[i] = this->m_associationData[j]; - } - this->m_associationData.remove(rowCount(QModelIndex())); + QMap >::Iterator it; + for (it = this->m_associationData.begin(); it != this->m_associationData.end();) { + if (it.value()[associationColumns::NodeID] == _nodeID) { + qCDebug(associationModel) << "Removing Node " << it.value()[associationColumns::NodeID] << it.key(); + this->beginRemoveRows(QModelIndex(), it.key(), it.key()); + it = this->m_associationData.erase(it); this->endRemoveRows(); - continue; + } else { + it++; } } } diff --git a/qt-openzwave/source/qtozwmanager.cpp b/qt-openzwave/source/qtozwmanager.cpp index 22ba332..07bad97 100644 --- a/qt-openzwave/source/qtozwmanager.cpp +++ b/qt-openzwave/source/qtozwmanager.cpp @@ -284,6 +284,9 @@ void QTOZWManager::connectSignals() { bool QTOZWManager::open(QString serialPort) { CALL_DPTR_RTN(open(serialPort), bool); } +bool QTOZWManager::close() { + CALL_DPTR_RTN(close(), bool); +} bool QTOZWManager::refreshNodeInfo(quint8 _node) { CALL_DPTR_RTN(refreshNodeInfo(_node), bool); } diff --git a/qt-openzwave/source/qtozwmanager_p.cpp b/qt-openzwave/source/qtozwmanager_p.cpp index f95809a..28805c0 100644 --- a/qt-openzwave/source/qtozwmanager_p.cpp +++ b/qt-openzwave/source/qtozwmanager_p.cpp @@ -144,7 +144,24 @@ bool QTOZWManager_Internal::open(QString SerialPort) return false; } qCDebug(manager) << "AddDriver Completed"; + this->m_SerialPort = SerialPort; + return true; +} +bool QTOZWManager_Internal::close() { + try { + if (this->m_manager->RemoveDriver(this->m_SerialPort.toStdString())) { + qCDebug(manager) << "Driver Removed for " << this->m_SerialPort; + } else { + qCWarning(manager) << "Couldn't Remove Driver for " << this->m_SerialPort; + } + } catch (OpenZWave::OZWException &e) { + emit this->error(QTOZWManagerErrorCodes::OZWException); + this->setErrorString(e.GetMsg().c_str()); + qCWarning(manager) << "Failed to Remove Driver: " << QString(e.GetMsg().c_str()); + return false; + } + this->m_SerialPort = QString(); return true; } @@ -876,10 +893,10 @@ void QTOZWManager_Internal::pvt_valueAdded(quint64 vidKey) void QTOZWManager_Internal::pvt_valueRemoved(quint64 vidKey) { qCDebug(notifications) << "Notification pvt_valueRemoved: " << vidKey; + emit this->valueRemoved(vidKey); if (this->m_validValues.contains(vidKey)) this->m_validValues.removeAll(vidKey); this->m_valueModel->delValue(vidKey); - emit this->valueRemoved(vidKey); } void QTOZWManager_Internal::pvt_valueChanged(quint64 vidKey) { @@ -1322,6 +1339,13 @@ void QTOZWManager_Internal::pvt_driverReady(quint32 _homeID) void QTOZWManager_Internal::pvt_driverFailed(quint32 _homeID) { qCDebug(notifications) << "Notification pvt_driverFailed " << _homeID; + QVector valueList(this->m_validValues); + for (QVector::Iterator it = valueList.begin(); it != valueList.end(); it++) + this->pvt_valueRemoved(*it); + QVector nodeList(this->m_validNodes); + for (QVector::iterator it = nodeList.begin(); it != nodeList.end(); it++) + this->pvt_nodeRemoved(*it); + this->m_associationsModel->resetModel(); this->m_valueModel->resetModel(); this->m_nodeModel->resetModel(); @@ -1332,6 +1356,13 @@ void QTOZWManager_Internal::pvt_driverFailed(quint32 _homeID) void QTOZWManager_Internal::pvt_driverReset(quint32 _homeID) { qCDebug(notifications) << "Notification pvt_driverReset " << _homeID; + QVector valueList(this->m_validValues); + for (QVector::Iterator it = valueList.begin(); it != valueList.end(); it++) + this->pvt_valueRemoved(*it); + QVector nodeList(this->m_validNodes); + for (QVector::iterator it = nodeList.begin(); it != nodeList.end(); it++) + this->pvt_nodeRemoved(*it); + this->m_associationsModel->resetModel(); this->m_valueModel->resetModel(); this->m_nodeModel->resetModel(); @@ -1342,6 +1373,13 @@ void QTOZWManager_Internal::pvt_driverReset(quint32 _homeID) void QTOZWManager_Internal::pvt_driverRemoved(quint32 _homeID) { qCDebug(notifications) << "Notification pvt_driverRemoved " << _homeID; + QVector valueList(this->m_validValues); + for (QVector::Iterator it = valueList.begin(); it != valueList.end(); it++) + this->pvt_valueRemoved(*it); + QVector nodeList(this->m_validNodes); + for (QVector::iterator it = nodeList.begin(); it != nodeList.end(); it++) + this->pvt_nodeRemoved(*it); + this->m_associationsModel->resetModel(); this->m_valueModel->resetModel(); this->m_nodeModel->resetModel(); diff --git a/qt-openzwave/source/qtozwnodemodel_p.cpp b/qt-openzwave/source/qtozwnodemodel_p.cpp index d270771..2e10706 100644 --- a/qt-openzwave/source/qtozwnodemodel_p.cpp +++ b/qt-openzwave/source/qtozwnodemodel_p.cpp @@ -88,21 +88,17 @@ void QTOZW_Nodes_internal::setNodeFlags(quint8 _nodeID, QTOZW_Nodes::nodeFlags _ } void QTOZW_Nodes_internal::delNode(quint8 _nodeID) { QMap >::iterator it; - QMap > newNodeMap; - int32_t newrow = 0; - for (it = this->m_nodeData.begin(); it != this->m_nodeData.end(); ++it) { + for (it = this->m_nodeData.begin(); it != this->m_nodeData.end();) { if (it.value()[QTOZW_Nodes::NodeColumns::NodeID] == _nodeID) { qCDebug(nodeModel) << "Removing Node " << it.value()[QTOZW_Nodes::NodeColumns::NodeID] << it.key(); this->beginRemoveRows(QModelIndex(), it.key(), it.key()); - this->m_nodeData.erase(it); + it = this->m_nodeData.erase(it); this->endRemoveRows(); continue; } else { - newNodeMap[newrow] = it.value(); - newrow++; + it++; } } - this->m_nodeData.swap(newNodeMap); } void QTOZW_Nodes_internal::resetModel() { diff --git a/qt-openzwave/source/qtozwnotification.cpp b/qt-openzwave/source/qtozwnotification.cpp index 72dac48..55eda5f 100644 --- a/qt-openzwave/source/qtozwnotification.cpp +++ b/qt-openzwave/source/qtozwnotification.cpp @@ -51,15 +51,6 @@ void OZWNotification::processNotification Q_UNUSED(_context); //qDebug() << QString(_notification->GetAsString().c_str()); //qDebug() << _notification; -#if 0 - void valueAdded(quint64 vidKey); - void valueRemoved(quint64 vidKey); - void valueChanged(quint64 vidKey); - void valueRefreshed(quint64 vidKey); - void valuePollingEnabled(quint64 vidKey); - void valuePollingDisabled(quint64 vidKey); -#endif - switch( _notification->GetType() ) { case OpenZWave::Notification::Type_ValueAdded: diff --git a/qt-openzwave/source/qtozwvalueidmodel_p.cpp b/qt-openzwave/source/qtozwvalueidmodel_p.cpp index c221d18..03cbc96 100644 --- a/qt-openzwave/source/qtozwvalueidmodel_p.cpp +++ b/qt-openzwave/source/qtozwvalueidmodel_p.cpp @@ -85,39 +85,32 @@ void QTOZW_ValueIds_internal::setValueFlags(quint64 _vidKey, QTOZW_ValueIds::Val void QTOZW_ValueIds_internal::delValue(quint64 _vidKey) { QMap >::iterator it; QMap > newValueMap; - int32_t newrow = 0; - for (it = this->m_valueData.begin(); it != this->m_valueData.end(); ++it) { + for (it = this->m_valueData.begin(); it != this->m_valueData.end();) { if (it.value()[QTOZW_ValueIds::ValueIdColumns::ValueIDKey] == _vidKey) { qCDebug(valueModel) << "Removing Value " << it.value()[QTOZW_ValueIds::ValueIdColumns::Label] << it.key(); this->beginRemoveRows(QModelIndex(), it.key(), it.key()); - this->m_valueData.erase(it); + it = this->m_valueData.erase(it); this->endRemoveRows(); continue; } else { - newValueMap[newrow] = it.value(); - newrow++; + it++; } } - this->m_valueData.swap(newValueMap); } void QTOZW_ValueIds_internal::delNodeValues(quint8 _node) { QMap >::iterator it; QMap > newValueMap; - qint32 newrow = 0; - for (it = this->m_valueData.begin(); it != this->m_valueData.end(); ++it) { + for (it = this->m_valueData.begin(); it != this->m_valueData.end();) { if (it.value()[QTOZW_ValueIds::ValueIdColumns::Node] == _node) { qCDebug(valueModel) << "Removing Value " << it.value()[QTOZW_ValueIds::ValueIdColumns::Label] << it.key(); this->beginRemoveRows(QModelIndex(), it.key(), it.key()); - this->m_valueData.erase(it); + it = this->m_valueData.erase(it); this->endRemoveRows(); - continue; } else { - newValueMap[newrow] = it.value(); - newrow++; + it++; } } - this->m_valueData.swap(newValueMap); } void QTOZW_ValueIds_internal::resetModel() { diff --git a/qt-ozwdaemon/mqttcommands/mqttcommands.cpp b/qt-ozwdaemon/mqttcommands/mqttcommands.cpp index 14888f9..e5c55c2 100644 --- a/qt-ozwdaemon/mqttcommands/mqttcommands.cpp +++ b/qt-ozwdaemon/mqttcommands/mqttcommands.cpp @@ -4,6 +4,7 @@ #include "mqttcommands/mqttcommands.h" #include "mqttcommands/ping.h" #include "mqttcommands/open.h" +#include "mqttcommands/close.h" #include "mqttcommands/refreshnodeinfo.h" #include "mqttcommands/requestNodeState.h" #include "mqttcommands/requestNodeDynamic.h" @@ -211,6 +212,7 @@ void MqttCommands::Register(QString command, pfnCreateCommand_t _create) { void MqttCommands::setupCommands() { this->Register(MqttCommand_Ping::StaticGetCommand(), &MqttCommand_Ping::Create); this->Register(MqttCommand_Open::StaticGetCommand(), &MqttCommand_Open::Create); + this->Register(MqttCommand_Close::StaticGetCommand(), &MqttCommand_Close::Create); this->Register(MqttCommand_RefreshNodeInfo::StaticGetCommand(), &MqttCommand_RefreshNodeInfo::Create); this->Register(MqttCommand_RequestNodeState::StaticGetCommand(), &MqttCommand_RequestNodeState::Create); this->Register(MqttCommand_RequestNodeDynamic::StaticGetCommand(), &MqttCommand_RequestNodeDynamic::Create); diff --git a/qt-ozwdaemon/mqttpublisher.cpp b/qt-ozwdaemon/mqttpublisher.cpp index 60ee1a8..72e53c3 100644 --- a/qt-ozwdaemon/mqttpublisher.cpp +++ b/qt-ozwdaemon/mqttpublisher.cpp @@ -378,6 +378,7 @@ void mqttpublisher::cleanTopics(QMqttMessage msg) { if (jsmsg.HasMember("Status") && (QString::fromStdString(jsmsg["Status"].GetString()) != "Offline")) { qCDebug(ozwmp) << "Unsubscribing from Topic Cleanup"; this->m_cleanTopicSubscription->unsubscribe(); + exit(-1); } return; } @@ -658,7 +659,6 @@ bool mqttpublisher::sendCommandClassUpdate(quint8 node, quint8 instance, quint8 return true; } - void mqttpublisher::sendCommandUpdate(QString command, rapidjson::Document &js) { QT2JS::SetUInt64(js, "TimeStamp", QDateTime::currentSecsSinceEpoch()); this->m_client->publish(QMqttTopicName(getCommandResponseTopic(command.toLower())), QT2JS::getJSON(js), 0, false); @@ -666,7 +666,7 @@ void mqttpublisher::sendCommandUpdate(QString command, rapidjson::Document &js) } bool mqttpublisher::delNodeTopic(quint8 node) { - this->m_client->publish(QMqttTopicName(getNodeTopic(MQTT_OZW_NODE_TOPIC, node)), NULL, 0, false); + this->m_client->publish(QMqttTopicName(getNodeTopic(MQTT_OZW_NODE_TOPIC, node)), NULL, 0, true); return true; } @@ -686,13 +686,22 @@ bool mqttpublisher::delValueTopic(quint64 vidKey) { qCWarning(ozwmp) << "sendValueUpdate: Can't find CC for Value: " << vidKey; return false; } - this->m_client->publish(QMqttTopicName(getValueTopic(MQTT_OZW_VID_TOPIC, node, instance, cc, vidKey)), NULL, 0, false); + this->m_client->publish(QMqttTopicName(getValueTopic(MQTT_OZW_VID_TOPIC, node, instance, cc, vidKey)), NULL, 0, true); /* XXX TODO: Scan though remaining Values, and see if any other Values are under the same CC or instance * if not - Then we should delete the CC/instance topic as well */ return true; } +bool mqttpublisher::delInstanceTopic(quint8 node, quint8 instance) { + this->m_client->publish(QMqttTopicName(getInstanceTopic(MQTT_OZW_INSTANCE_TOPIC, node, instance)), NULL, 0, true); + return true; +} + +bool mqttpublisher::delCommandClassTopic(quint8 node, quint8 instance, quint8 cc) { + this->m_client->publish(QMqttTopicName(getCommandClassTopic(MQTT_OZW_COMMANDCLASS_TOPIC, node, instance, cc)), NULL, 0, true); + return true; +} void mqttpublisher::ready() { qCDebug(ozwmp) << "Publishing Event ready:"; diff --git a/qt-ozwdaemon/mqttpublisher.h b/qt-ozwdaemon/mqttpublisher.h index 79bd811..630162f 100644 --- a/qt-ozwdaemon/mqttpublisher.h +++ b/qt-ozwdaemon/mqttpublisher.h @@ -113,6 +113,8 @@ private: bool sendCommandClassUpdate(quint8, quint8, quint8); bool delNodeTopic(quint8); bool delValueTopic(quint64); + bool delInstanceTopic(quint8, quint8); + bool delCommandClassTopic(quint8, quint8, quint8); rapidjson::Document *getInstanceJSON(quint8, quint8); rapidjson::Document *getCommandClassJSON(quint8, quint8, quint8); diff --git a/qt-ozwdaemon/qt-ozwdaemon.pro b/qt-ozwdaemon/qt-ozwdaemon.pro index 2d4fdc0..a24c814 100644 --- a/qt-ozwdaemon/qt-ozwdaemon.pro +++ b/qt-ozwdaemon/qt-ozwdaemon.pro @@ -27,6 +27,7 @@ qtHaveModule(mqtt) { mqttcommands/mqttcommands.cpp \ mqttcommands/ping.cpp \ mqttcommands/open.cpp \ + mqttcommands/close.cpp \ mqttcommands/refreshnodeinfo.cpp \ mqttcommands/requestNodeState.cpp \ mqttcommands/requestNodeDynamic.cpp \ @@ -61,6 +62,7 @@ qtHaveModule(mqtt) { mqttcommands/mqttcommands.h \ mqttcommands/ping.h \ mqttcommands/open.h \ + mqttcommands/close.h \ mqttcommands/refreshnodeinfo.h \ mqttcommands/requestNodeState.h \ mqttcommands/requestNodeDynamic.h \