Node and Value Removals and Clear MQTT Topics when closing OZW

This commit is contained in:
Justin Hammond 2019-11-13 16:33:43 +08:00
parent f8e01864d8
commit 7095f863f4
10 changed files with 145 additions and 52 deletions

View file

@ -93,6 +93,6 @@ protected:
QVariant getNodeData(quint8, NodeColumns);
int32_t getNodeRow(quint8 _node);
QMap<int32_t, QMap<NodeColumns, QVariant> > m_nodeData;
QVector< QMap<NodeColumns, QVariant> > m_nodeData;
};
#endif // QTOZWNODEMODEL_H

View file

@ -120,7 +120,7 @@ protected:
QVariant getValueData(quint64, ValueIdColumns);
int32_t getValueRow(quint64 _node);
QMap<int32_t, QMap<ValueIdColumns, QVariant> > m_valueData;
QVector< QMap<ValueIdColumns, QVariant> > m_valueData;
};
#endif // QTOZWVALUEIDMODEL_H

View file

@ -44,6 +44,7 @@ public Q_SLOTS:
void delNode(quint8 _nodeID);
void resetModel();
void finishTransaction(quint8 _nodeID);
};

View file

@ -45,6 +45,8 @@ public Q_SLOTS:
void delNodeValues(quint8 _node);
void resetModel();
void finishTransaction(quint64 _vidKey);
QVariant getValueData(quint64, ValueIdColumns);
};

View file

@ -161,6 +161,26 @@ bool QTOZWManager_Internal::close() {
qCWarning(manager) << "Failed to Remove Driver: " << QString(e.GetMsg().c_str());
return false;
}
try {
if (this->m_manager->RemoveWatcher(OZWNotification::processNotification, this ) != true) {
emit this->error(QTOZWManagerErrorCodes::setupFailed);
this->setErrorString("Failed to Remove Notification Callback");
qCWarning(manager) << "Failed to Remove Notification Callback";
return false;
}
} catch (OpenZWave::OZWException &e) {
emit this->error(QTOZWManagerErrorCodes::OZWException);
this->setErrorString(e.GetMsg().c_str());
qCWarning(manager) << "Failed to Remove Notification Callback " << QString(e.GetMsg().c_str());
return false;
}
if (OZWNotification::Get()->disconnect() != true) {
emit this->error(QTOZWManagerErrorCodes::setupFailed);
this->setErrorString("Failed to Disconnect Notification Signals");
qCWarning(manager) << "Failed to Disconnect Notification Signals";
return false;
}
qCDebug(manager) << "OZW Serial Port Closed";
this->m_SerialPort = QString();
return true;
}
@ -1016,18 +1036,33 @@ void QTOZWManager_Internal::pvt_nodeAdded(quint8 node)
void QTOZWManager_Internal::pvt_nodeRemoved(quint8 node)
{
qCDebug(notifications) << "Notification pvt_nodeRemoved " << node;
QVector<quint64> valueList(this->m_validValues);
for (QVector<quint64>::Iterator it = valueList.begin(); it != valueList.end(); it++) {
if (this->m_valueModel->getValueData(*it, QTOZW_ValueIds::ValueIdColumns::Node).toInt() == node)
this->pvt_valueRemoved(*it);
}
emit this->nodeRemoved(node);
if (this->m_validNodes.contains(node))
this->m_validNodes.removeAll(node);
this->m_associationsModel->delNode(node);
/* technically, this shouldn't be required... but just in case */
this->m_valueModel->delNodeValues(node);
this->m_nodeModel->delNode(node);
emit this->nodeRemoved(node);
}
void QTOZWManager_Internal::pvt_nodeReset(quint8 node)
{
qCDebug(notifications) << "Notification pvt_nodeReset " << node;
QVector<quint64> valueList(this->m_validValues);
for (QVector<quint64>::Iterator it = valueList.begin(); it != valueList.end(); it++) {
if (this->m_valueModel->getValueData(*it, QTOZW_ValueIds::ValueIdColumns::Node).toInt() == node)
this->pvt_valueRemoved(*it);
}
emit this->nodeReset(node);
if (this->m_validNodes.contains(node))
this->m_validNodes.removeAll(node);
@ -1035,7 +1070,6 @@ void QTOZWManager_Internal::pvt_nodeReset(quint8 node)
/* technically, this shouldn't be required... but just in case */
this->m_valueModel->delNodeValues(node);
this->m_nodeModel->delNode(node);
emit this->nodeReset(node);
}
void QTOZWManager_Internal::pvt_nodeNaming(quint8 node)
@ -1339,9 +1373,6 @@ void QTOZWManager_Internal::pvt_driverReady(quint32 _homeID)
void QTOZWManager_Internal::pvt_driverFailed(quint32 _homeID)
{
qCDebug(notifications) << "Notification pvt_driverFailed " << _homeID;
QVector<quint64> valueList(this->m_validValues);
for (QVector<quint64>::Iterator it = valueList.begin(); it != valueList.end(); it++)
this->pvt_valueRemoved(*it);
QVector<quint8> nodeList(this->m_validNodes);
for (QVector<quint8>::iterator it = nodeList.begin(); it != nodeList.end(); it++)
this->pvt_nodeRemoved(*it);
@ -1356,9 +1387,6 @@ void QTOZWManager_Internal::pvt_driverFailed(quint32 _homeID)
void QTOZWManager_Internal::pvt_driverReset(quint32 _homeID)
{
qCDebug(notifications) << "Notification pvt_driverReset " << _homeID;
QVector<quint64> valueList(this->m_validValues);
for (QVector<quint64>::Iterator it = valueList.begin(); it != valueList.end(); it++)
this->pvt_valueRemoved(*it);
QVector<quint8> nodeList(this->m_validNodes);
for (QVector<quint8>::iterator it = nodeList.begin(); it != nodeList.end(); it++)
this->pvt_nodeRemoved(*it);
@ -1373,9 +1401,6 @@ void QTOZWManager_Internal::pvt_driverReset(quint32 _homeID)
void QTOZWManager_Internal::pvt_driverRemoved(quint32 _homeID)
{
qCDebug(notifications) << "Notification pvt_driverRemoved " << _homeID;
QVector<quint64> valueList(this->m_validValues);
for (QVector<quint64>::Iterator it = valueList.begin(); it != valueList.end(); it++)
this->pvt_valueRemoved(*it);
QVector<quint8> nodeList(this->m_validNodes);
for (QVector<quint8>::iterator it = nodeList.begin(); it != nodeList.end(); it++)
this->pvt_nodeRemoved(*it);

View file

@ -56,7 +56,7 @@ QVariant QTOZW_Nodes::data(const QModelIndex &index, int role) const {
return QVariant();
if (role == Qt::DisplayRole) {
QMap<NodeColumns, QVariant> node = this->m_nodeData[index.row()];
QMap<NodeColumns, QVariant> node = this->m_nodeData.at(index.row());
if (node.size() == 0) {
qCWarning(nodeModel) << "data: Cant find any Node on Row " << index.row();
return QVariant();
@ -171,7 +171,7 @@ bool QTOZW_Nodes::setData(const QModelIndex &index, const QVariant &value, int r
switch (static_cast<NodeColumns>(index.column())) {
case NodeName:
case NodeLocation:
if (this->m_nodeData[index.row()][static_cast<NodeColumns>(index.column())] != value) {
if (this->m_nodeData.at(index.row())[static_cast<NodeColumns>(index.column())] != value) {
this->m_nodeData[index.row()][static_cast<NodeColumns>(index.column())] = value;
QVector<int> roles;
roles << Qt::DisplayRole << QTOZW_UserRoles::ModelDataChanged;
@ -187,7 +187,7 @@ bool QTOZW_Nodes::setData(const QModelIndex &index, const QVariant &value, int r
QVariant QTOZW_Nodes::getNodeData(quint8 _node, QTOZW_Nodes::NodeColumns _column) {
int32_t row = this->getNodeRow(_node);
if (row >= 0)
return this->m_nodeData[row][_column];
return this->m_nodeData.at(row)[_column];
qCWarning(nodeModel) << "Can't find NodeData for Node " << _node;
return QVariant();
}
@ -196,12 +196,14 @@ int32_t QTOZW_Nodes::getNodeRow(quint8 _node) {
if (this->m_nodeData.count() == 0) {
return -1;
}
QMap<int32_t, QMap<NodeColumns, QVariant> >::iterator it;
QVector< QMap<NodeColumns, QVariant> >::iterator it;
int i = 0;
for (it = m_nodeData.begin(); it != m_nodeData.end(); ++it) {
QMap<NodeColumns, QVariant> node = it.value();
QMap<NodeColumns, QVariant> node = (*it);
if (node.value(QTOZW_Nodes::NodeID) == _node) {
return it.key();
return i;
}
i++;
}
//qCWarning(nodeModel) << "Can't Find NodeID " << _node << " in NodeData";
return -1;

View file

@ -48,7 +48,7 @@ void QTOZW_Nodes_internal::addNode(quint8 _nodeID)
newNode[QTOZW_Nodes::NodeFlags] = flags;
this->beginInsertRows(QModelIndex(), this->rowCount(QModelIndex()), this->rowCount(QModelIndex()));
this->m_nodeData[this->rowCount(QModelIndex())] = newNode;
this->m_nodeData.push_back(newNode);
this->endInsertRows();
qCInfo(nodeModel) << "Adding Node " << _nodeID << "At Row " << this->getNodeRow(_nodeID);
}
@ -60,7 +60,7 @@ void QTOZW_Nodes_internal::setNodeData(quint8 _nodeID, QTOZW_Nodes::NodeColumns
qCWarning(nodeModel) << "setNodeData: Node " << _nodeID << " does not exist";
return;
}
if (this->m_nodeData[row][column] != data) {
if (this->m_nodeData.at(row)[column] != data) {
this->m_nodeData[row][column] = data;
QVector<int> roles;
roles << Qt::DisplayRole;
@ -77,7 +77,7 @@ void QTOZW_Nodes_internal::setNodeFlags(quint8 _nodeID, QTOZW_Nodes::nodeFlags _
qCWarning(nodeModel) << "setNodeData: Node " << _nodeID << " does not exist";
return;
}
QBitArray flag = this->m_nodeData[row][QTOZW_Nodes::NodeFlags].toBitArray();
QBitArray flag = this->m_nodeData.at(row)[QTOZW_Nodes::NodeFlags].toBitArray();
if (flag.at(_flags) != _value) {
flag.setBit(_flags, _value);
this->m_nodeData[row][QTOZW_Nodes::NodeFlags] = flag;
@ -87,17 +87,19 @@ void QTOZW_Nodes_internal::setNodeFlags(quint8 _nodeID, QTOZW_Nodes::nodeFlags _
}
}
void QTOZW_Nodes_internal::delNode(quint8 _nodeID) {
QMap<int32_t, QMap<NodeColumns, QVariant> >::iterator it;
QVector< QMap<NodeColumns, QVariant> >::iterator it;
int i = 0;
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());
if ((*it)[QTOZW_Nodes::NodeColumns::NodeID] == _nodeID) {
qCDebug(nodeModel) << "Removing Node " << (*it)[QTOZW_Nodes::NodeColumns::NodeID] << i;
this->beginRemoveRows(QModelIndex(), i, i);
it = this->m_nodeData.erase(it);
this->endRemoveRows();
continue;
} else {
it++;
}
i++;
}
}

View file

@ -75,26 +75,29 @@ int QTOZW_ValueIds::columnCount(const QModelIndex &parent) const {
QVariant QTOZW_ValueIds::data(const QModelIndex &index, int role) const {
if (!index.isValid())
return QVariant();
//qDebug() << "data" << index.row() << this->rowCount(index.parent());
if (index.row() >= this->rowCount(index.parent()) || index.row() < 0)
return QVariant();
if (role == Qt::DisplayRole) {
QMap<ValueIdColumns, QVariant> value = this->m_valueData[index.row()];
//qDebug() << "Doing Display Data";
QMap<ValueIdColumns, QVariant> value = this->m_valueData.at(index.row());
if (value.size() == 0) {
qCWarning(valueModel) << "data: Cant find any Node on Row " << index.row();
return QVariant();
}
//qDebug() << value[ValueIdColumns::ValueIDKey] << QMetaEnum::fromType<ValueIdColumns>().valueToKey(index.column()) << value;
return value[static_cast<ValueIdColumns>(index.column())];
}
if (role == Qt::ToolTipRole) {
QMap<ValueIdColumns, QVariant> value = this->m_valueData[index.row()];
QMap<ValueIdColumns, QVariant> value = this->m_valueData.at(index.row());
if (value.size() == 0) {
qCWarning(valueModel) << "data: Cant find any Node on Row " << index.row();
return QVariant();
}
return value[static_cast<ValueIdColumns>(ValueIdColumns::Help)];
}
//qDebug() << "Returning Invalid";
return QVariant();
}
@ -172,11 +175,10 @@ bool QTOZW_ValueIds::setData(const QModelIndex &index, const QVariant &value, in
if (role != Qt::EditRole) {
return false;
}
switch (static_cast<ValueIdColumns>(index.column())) {
case Value:
if (this->m_valueData[index.row()][static_cast<ValueIdColumns>(index.column())] != value) {
this->m_valueData[index.row()][static_cast<ValueIdColumns>(index.column())] = value;
if (this->m_valueData.at(index.row())[static_cast<ValueIdColumns>(index.column())] != value) {
this->m_valueData.value(index.row())[static_cast<ValueIdColumns>(index.column())] = value;
QVector<int> roles;
roles << Qt::DisplayRole << QTOZW_UserRoles::ModelDataChanged;
this->dataChanged(index, index, roles);
@ -190,8 +192,8 @@ bool QTOZW_ValueIds::setData(const QModelIndex &index, const QVariant &value, in
QVariant QTOZW_ValueIds::getValueData(quint64 _vidKey, ValueIdColumns _column) {
int32_t row = this->getValueRow(_vidKey);
if (row >= 0)
return this->m_valueData[row][_column];
if (row != -1)
return this->m_valueData.at(row)[_column];
qCWarning(valueModel) << "Can't find ValueData for ValueID " << _vidKey;
return QVariant();
}
@ -200,12 +202,16 @@ int32_t QTOZW_ValueIds::getValueRow(quint64 _vidKey) {
if (this->m_valueData.count() == 0) {
return -1;
}
QMap<int32_t, QMap<ValueIdColumns, QVariant> >::iterator it;
//qDebug() << "ValueModel Size:" << m_valueData.count();
QVector< QMap<ValueIdColumns, QVariant> >::iterator it;
int i = 0;
for (it = m_valueData.begin(); it != m_valueData.end(); ++it) {
QMap<ValueIdColumns, QVariant> node = it.value();
QMap<ValueIdColumns, QVariant> node = (*it);
//qDebug() << node.value(ValueIdColumns::ValueIDKey) << _vidKey;
if (node.value(ValueIdColumns::ValueIDKey) == _vidKey) {
return it.key();
return i;
}
i++;
}
//qCWarning(valueModel) << "Can't Find ValueID " << _vidKey << " in valueData";
return -1;

View file

@ -46,7 +46,7 @@ void QTOZW_ValueIds_internal::addValue(quint64 _vidKey)
newValue[QTOZW_ValueIds::ValueFlags] = flags;
this->beginInsertRows(QModelIndex(), this->rowCount(QModelIndex()), this->rowCount(QModelIndex()));
this->m_valueData[this->rowCount(QModelIndex())] = newValue;
this->m_valueData.push_back(newValue);
this->endInsertRows();
}
@ -57,11 +57,12 @@ void QTOZW_ValueIds_internal::setValueData(quint64 _vidKey, QTOZW_ValueIds::Valu
qCWarning(valueModel) << "setValueData: Value " << _vidKey << " does not exist";
return;
}
if (this->m_valueData[row][column] != data) {
if (this->m_valueData.at(row)[column] != data) {
this->m_valueData[row][column] = data;
QVector<int> roles;
roles << Qt::DisplayRole;
if (!transaction) this->dataChanged(this->createIndex(row, column), this->createIndex(row, column), roles);
//qDebug() << "Setting Data " << _vidKey << row << QMetaEnum::fromType<ValueIdColumns>().valueToKey(column) << data << this->m_valueData.value(row)[column] << this->m_valueData.at(row)[ValueIdColumns::ValueIDKey];
}
}
@ -72,10 +73,10 @@ void QTOZW_ValueIds_internal::setValueFlags(quint64 _vidKey, QTOZW_ValueIds::Val
qCWarning(valueModel) << "setValueFlags: Value " << _vidKey << " does not exist";
return;
}
if (this->m_valueData[row][QTOZW_ValueIds::ValueFlags].toBitArray().at(_flags) != _value) {
QBitArray flags = this->m_valueData[row][QTOZW_ValueIds::ValueFlags].value<QBitArray>();
if (this->m_valueData.at(row)[QTOZW_ValueIds::ValueFlags].toBitArray().at(_flags) != _value) {
QBitArray flags = this->m_valueData.value(row)[QTOZW_ValueIds::ValueFlags].value<QBitArray>();
flags.setBit(_flags, _value);
this->m_valueData[row][QTOZW_ValueIds::ValueFlags] = flags;
this->m_valueData.value(row)[QTOZW_ValueIds::ValueFlags] = flags;
QVector<int> roles;
roles << Qt::DisplayRole;
if (!transaction) this->dataChanged(this->createIndex(row, QTOZW_ValueIds::ValueFlags), this->createIndex(row, QTOZW_ValueIds::ValueFlags), roles);
@ -83,33 +84,35 @@ void QTOZW_ValueIds_internal::setValueFlags(quint64 _vidKey, QTOZW_ValueIds::Val
}
void QTOZW_ValueIds_internal::delValue(quint64 _vidKey) {
QMap<int32_t, QMap<ValueIdColumns, QVariant> >::iterator it;
QMap<int32_t, QMap<ValueIdColumns, QVariant> > newValueMap;
QVector< QMap<ValueIdColumns, QVariant> >::iterator it;
int i = 0;
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());
if ((*it)[QTOZW_ValueIds::ValueIdColumns::ValueIDKey] == _vidKey) {
qCDebug(valueModel) << "delValue: Removing Value " << (*it)[QTOZW_ValueIds::ValueIdColumns::Label] << (*it)[QTOZW_ValueIds::ValueIdColumns::ValueIDKey] << i;
this->beginRemoveRows(QModelIndex(), i, i);
it = this->m_valueData.erase(it);
this->endRemoveRows();
continue;
} else {
it++;
}
i++;
}
}
void QTOZW_ValueIds_internal::delNodeValues(quint8 _node) {
QMap<int32_t, QMap<ValueIdColumns, QVariant> >::iterator it;
QMap<int32_t, QMap<ValueIdColumns, QVariant> > newValueMap;
QVector< QMap<ValueIdColumns, QVariant> >::iterator it;
int i = 0;
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());
if ((*it)[QTOZW_ValueIds::ValueIdColumns::Node] == _node) {
qCDebug(valueModel) << "delNodeValue: Removing Value " << (*it)[QTOZW_ValueIds::ValueIdColumns::Label] << (*it)[QTOZW_ValueIds::ValueIdColumns::ValueIDKey] << i;
this->beginRemoveRows(QModelIndex(), i, i);
it = this->m_valueData.erase(it);
this->endRemoveRows();
} else {
it++;
}
i++;
}
}
@ -128,6 +131,9 @@ void QTOZW_ValueIds_internal::finishTransaction(quint64 _vidKey) {
this->dataChanged(this->createIndex(row, 0), this->createIndex(row, QTOZW_ValueIds::ValueIdColumns::ValueIdCount -1));
}
QVariant QTOZW_ValueIds_internal::getValueData(quint64 node, ValueIdColumns column) {
return QTOZW_ValueIds::getValueData(node, column);
}
QString BitSettoQString(QBitArray ba) {

View file

@ -745,6 +745,55 @@ void mqttpublisher::valueAdded(quint64 vidKey) {
void mqttpublisher::valueRemoved(quint64 vidKey) {
qCDebug(ozwmp) << "Publishing Event valueRemoved:" << vidKey;
this->delValueTopic(vidKey);
quint8 vinstance = this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Instance).toInt();
quint8 vcc = this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::CommandClass).toInt();
quint8 node = this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Node).toInt();
bool removeInstance = true;
bool removeCC = true;
QMap<quint64, rapidjson::Document *>::iterator it;
for (it =this->m_values.begin(); it != this->m_values.end(); it++) {
if (this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::ValueIDKey).value<quint64>() == vidKey) {
continue;
}
if (this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::Node).toInt() != node) {
continue;
}
if (this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::Instance).toInt() != vinstance) {
continue;
};
quint8 cc = this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::CommandClass).toInt();
if (vcc == cc) {
removeCC = false;
}
}
if (removeCC) {
qCDebug(ozwmp) << "Removing CommandClass Topic for " << this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Node).toInt() << vinstance << vcc;
this->delCommandClassTopic(this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Node).toInt(), vinstance, vcc);
}
for (it =this->m_values.begin(); it != this->m_values.end(); it++) {
if (this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::ValueIDKey).value<quint64>() == vidKey) {
continue;
}
if (this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::Node).toInt() != node) {
continue;
}
quint8 instance = this->m_valueModel->getValueData(it.key(), QTOZW_ValueIds::ValueIdColumns::Instance).toInt();
if (vinstance == instance) {
removeInstance = false;
}
}
if (removeInstance) {
qCDebug(ozwmp) << "Removing Instance Topic for " << this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Node).toInt() << vinstance;
this->delInstanceTopic(this->m_valueModel->getValueData(vidKey, QTOZW_ValueIds::ValueIdColumns::Node).toInt(), vinstance);
}
if (this->m_values.find(vidKey) != this->m_values.end()) {
this->m_values.remove(vidKey);
} else {
qCWarning(ozwmp) << "Can't Find Value Map for " << vidKey;
}
}
void mqttpublisher::valueChanged(quint64 vidKey) {
qCDebug(ozwmp) << "Publishing Event valueChanged:" << vidKey;