Update database and add lqi and timestamp for nodes
This commit is contained in:
parent
ed5517fbf1
commit
5cc83bb956
@ -243,7 +243,7 @@ void ZigbeeNetwork::removeZigbeeNode(const ZigbeeAddress &address)
|
|||||||
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, this, [this, zdoReply, node](){
|
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, this, [this, zdoReply, node](){
|
||||||
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to send management leave request to" << node << zdoReply->error();
|
qCWarning(dcZigbeeNode()) << "Failed to send management leave request to" << node << zdoReply->error();
|
||||||
qCWarning(dcZigbeeNode()) << "This node is gonna be removed internally and tried to remove once it shows up the next time.";
|
qCWarning(dcZigbeeNode()) << "This node is gonna be removed internally. TODO: try to remove using ZDO once it shows up the next time.";
|
||||||
}
|
}
|
||||||
|
|
||||||
removeNode(node);
|
removeNode(node);
|
||||||
@ -264,7 +264,15 @@ void ZigbeeNetwork::addNodeInternally(ZigbeeNode *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: check when and how the note will be reachable
|
// FIXME: check when and how the note will be reachable
|
||||||
//node->setConnected(state() == StateRunning);
|
|
||||||
|
// Update database metrics of the node
|
||||||
|
connect(node, &ZigbeeNode::lqiChanged, this, [this, node](quint8 lqi){
|
||||||
|
m_database->updateNodeLqi(node, lqi);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(node, &ZigbeeNode::lastSeenChanged, this, [this, node](const QDateTime &lastSeen){
|
||||||
|
m_database->updateNodeLastSeen(node, lastSeen);
|
||||||
|
});
|
||||||
|
|
||||||
// Note: if a cluster shows up after initialization (out of spec devices), save the cluster and it's attributes
|
// Note: if a cluster shows up after initialization (out of spec devices), save the cluster and it's attributes
|
||||||
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
||||||
|
|||||||
@ -74,12 +74,16 @@ QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes()
|
|||||||
quint16 shortAddress = nodesQuery.value("shortAddress").toUInt();
|
quint16 shortAddress = nodesQuery.value("shortAddress").toUInt();
|
||||||
QByteArray nodeDescriptor = QByteArray::fromBase64(nodesQuery.value("nodeDescriptor").toByteArray());
|
QByteArray nodeDescriptor = QByteArray::fromBase64(nodesQuery.value("nodeDescriptor").toByteArray());
|
||||||
quint16 powerDescriptor = nodesQuery.value("powerDescriptor").toUInt();
|
quint16 powerDescriptor = nodesQuery.value("powerDescriptor").toUInt();
|
||||||
|
quint8 lqi = nodesQuery.value("lqi").toUInt();
|
||||||
|
quint64 lastSeen = nodesQuery.value("timestamp").toULongLong();
|
||||||
|
|
||||||
// Build the node object
|
// Build the node object
|
||||||
ZigbeeNode *node = new ZigbeeNode(m_network, shortAddress, ZigbeeAddress(ieeeAddress), m_network);
|
ZigbeeNode *node = new ZigbeeNode(m_network, shortAddress, ZigbeeAddress(ieeeAddress), m_network);
|
||||||
node->m_nodeDescriptor = ZigbeeDeviceProfile::parseNodeDescriptor(nodeDescriptor);
|
node->m_nodeDescriptor = ZigbeeDeviceProfile::parseNodeDescriptor(nodeDescriptor);
|
||||||
node->m_macCapabilities = node->nodeDescriptor().macCapabilities;
|
node->m_macCapabilities = node->nodeDescriptor().macCapabilities;
|
||||||
node->m_powerDescriptor = ZigbeeDeviceProfile::parsePowerDescriptor(powerDescriptor);
|
node->m_powerDescriptor = ZigbeeDeviceProfile::parsePowerDescriptor(powerDescriptor);
|
||||||
|
node->m_lqi = lqi;
|
||||||
|
node->m_lastSeen = QDateTime::fromMSecsSinceEpoch(lastSeen * 1000);
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetworkDatabase()) << "Loaded" << node;
|
qCDebug(dcZigbeeNetworkDatabase()) << "Loaded" << node;
|
||||||
|
|
||||||
@ -202,9 +206,9 @@ bool ZigbeeNetworkDatabase::initDatabase()
|
|||||||
"(ieeeAddress TEXT PRIMARY KEY, " // ieeeAddress to string
|
"(ieeeAddress TEXT PRIMARY KEY, " // ieeeAddress to string
|
||||||
"shortAddress INTEGER NOT NULL, " // uint16
|
"shortAddress INTEGER NOT NULL, " // uint16
|
||||||
"nodeDescriptor BLOB NOT NULL, " // bytes as received from the node
|
"nodeDescriptor BLOB NOT NULL, " // bytes as received from the node
|
||||||
"powerDescriptor INTEGER NOT NULL, "
|
"powerDescriptor INTEGER NOT NULL, " // uint16
|
||||||
"lqi INTEGER,"
|
"lqi INTEGER NOT NULL," // uint8
|
||||||
"timestamp )"); // uint16
|
"timestamp INTEGER NOT NULL)"); // unix timestamp with the last communication
|
||||||
createIndices("ieeeAddressIndex", "nodes", "ieeeAddress");
|
createIndices("ieeeAddressIndex", "nodes", "ieeeAddress");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,12 +383,14 @@ bool ZigbeeNetworkDatabase::saveAttribute(ZigbeeCluster *cluster, const ZigbeeCl
|
|||||||
bool ZigbeeNetworkDatabase::saveNode(ZigbeeNode *node)
|
bool ZigbeeNetworkDatabase::saveNode(ZigbeeNode *node)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetworkDatabase()) << "Save" << node;
|
qCDebug(dcZigbeeNetworkDatabase()) << "Save" << node;
|
||||||
QString queryString = QString("INSERT OR REPLACE INTO nodes (ieeeAddress, shortAddress, nodeDescriptor, powerDescriptor) "
|
QString queryString = QString("INSERT OR REPLACE INTO nodes (ieeeAddress, shortAddress, nodeDescriptor, powerDescriptor, lqi, timestamp) "
|
||||||
"VALUES (\"%1\", \"%2\", \"%3\", \"%4\");")
|
"VALUES (\"%1\", \"%2\", \"%3\", \"%4\", \"%5\", \"%6\");")
|
||||||
.arg(node->extendedAddress().toString())
|
.arg(node->extendedAddress().toString())
|
||||||
.arg(node->shortAddress())
|
.arg(node->shortAddress())
|
||||||
.arg(node->nodeDescriptor().descriptorRawData.toBase64().data()) // Note: convert to base64 for saving zeros as string
|
.arg(node->nodeDescriptor().descriptorRawData.toBase64().data()) // Note: convert to base64 for saving zeros as string
|
||||||
.arg(node->powerDescriptor().powerDescriptoFlag);
|
.arg(node->powerDescriptor().powerDescriptoFlag)
|
||||||
|
.arg(node->lqi())
|
||||||
|
.arg(node->lastSeen().toMSecsSinceEpoch() / 1000);
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetworkDatabase()) << queryString;
|
qCDebug(dcZigbeeNetworkDatabase()) << queryString;
|
||||||
m_db.exec(queryString);
|
m_db.exec(queryString);
|
||||||
@ -403,6 +409,33 @@ bool ZigbeeNetworkDatabase::saveNode(ZigbeeNode *node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigbeeNetworkDatabase::updateNodeLqi(ZigbeeNode *node, quint8 lqi)
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeNetworkDatabase()) << "Update nod LQI" << node << lqi;
|
||||||
|
QString queryString = QString("UPDATE nodes SET lqi = \"%1\" WHERE ieeeAddress = \"%2\";").arg(lqi).arg(node->extendedAddress().toString());
|
||||||
|
m_db.exec(queryString);
|
||||||
|
if (m_db.lastError().type() != QSqlError::NoError) {
|
||||||
|
qCWarning(dcZigbeeNetworkDatabase()) << "Could not update node LQI value in the database." << queryString << m_db.lastError().databaseText() << m_db.lastError().driverText();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeNetworkDatabase::updateNodeLastSeen(ZigbeeNode *node, const QDateTime &lastSeen)
|
||||||
|
{
|
||||||
|
quint64 timestamp = lastSeen.toMSecsSinceEpoch() / 1000;
|
||||||
|
qCDebug(dcZigbeeNetworkDatabase()) << "Update node last seen UTC timestamp" << node << timestamp;
|
||||||
|
QString queryString = QString("UPDATE nodes SET timestamp = \"%1\" WHERE ieeeAddress = \"%2\";").arg(timestamp).arg(node->extendedAddress().toString());
|
||||||
|
m_db.exec(queryString);
|
||||||
|
if (m_db.lastError().type() != QSqlError::NoError) {
|
||||||
|
qCWarning(dcZigbeeNetworkDatabase()) << "Could not update node timestamp value in the database." << queryString << m_db.lastError().databaseText() << m_db.lastError().driverText();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ZigbeeNetworkDatabase::removeNode(ZigbeeNode *node)
|
bool ZigbeeNetworkDatabase::removeNode(ZigbeeNode *node)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetworkDatabase()) << "Remove" << node;
|
qCDebug(dcZigbeeNetworkDatabase()) << "Remove" << node;
|
||||||
|
|||||||
@ -63,7 +63,8 @@ public slots:
|
|||||||
bool saveOutputCluster(ZigbeeCluster *cluster);
|
bool saveOutputCluster(ZigbeeCluster *cluster);
|
||||||
bool saveAttribute(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
bool saveAttribute(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
||||||
bool saveNode(ZigbeeNode *node);
|
bool saveNode(ZigbeeNode *node);
|
||||||
|
bool updateNodeLqi(ZigbeeNode *node, quint8 lqi);
|
||||||
|
bool updateNodeLastSeen(ZigbeeNode *node, const QDateTime &lastSeen);
|
||||||
bool removeNode(ZigbeeNode *node);
|
bool removeNode(ZigbeeNode *node);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -92,6 +92,11 @@ quint8 ZigbeeNode::lqi() const
|
|||||||
return m_lqi;
|
return m_lqi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDateTime ZigbeeNode::lastSeen() const
|
||||||
|
{
|
||||||
|
return m_lastSeen;
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeDeviceProfile::NodeDescriptor ZigbeeNode::nodeDescriptor() const
|
ZigbeeDeviceProfile::NodeDescriptor ZigbeeNode::nodeDescriptor() const
|
||||||
{
|
{
|
||||||
return m_nodeDescriptor;
|
return m_nodeDescriptor;
|
||||||
@ -548,6 +553,11 @@ void ZigbeeNode::handleDataIndication(const Zigbee::ApsdeDataIndication &indicat
|
|||||||
emit lqiChanged(m_lqi);
|
emit lqiChanged(m_lqi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the UTC timestamp of last seen for reachable verification
|
||||||
|
if (m_lastSeen != QDateTime::currentDateTimeUtc()) {
|
||||||
|
m_lastSeen = QDateTime::currentDateTimeUtc();
|
||||||
|
emit lastSeenChanged(m_lastSeen);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if this indocation is related to any pending reply
|
// Check if this indocation is related to any pending reply
|
||||||
if (indication.profileId == Zigbee::ZigbeeProfileDevice) {
|
if (indication.profileId == Zigbee::ZigbeeProfileDevice) {
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#define ZIGBEENODE_H
|
#define ZIGBEENODE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
#include "zigbeeaddress.h"
|
#include "zigbeeaddress.h"
|
||||||
@ -66,6 +67,7 @@ public:
|
|||||||
ZigbeeNodeEndpoint *getEndpoint(quint8 endpointId) const;
|
ZigbeeNodeEndpoint *getEndpoint(quint8 endpointId) const;
|
||||||
|
|
||||||
quint8 lqi() const;
|
quint8 lqi() const;
|
||||||
|
QDateTime lastSeen() const;
|
||||||
|
|
||||||
// Information from descriptors
|
// Information from descriptors
|
||||||
ZigbeeDeviceProfile::NodeDescriptor nodeDescriptor() const;
|
ZigbeeDeviceProfile::NodeDescriptor nodeDescriptor() const;
|
||||||
@ -93,6 +95,7 @@ private:
|
|||||||
bool m_connected = false;
|
bool m_connected = false;
|
||||||
State m_state = StateUninitialized;
|
State m_state = StateUninitialized;
|
||||||
quint8 m_lqi = 0;
|
quint8 m_lqi = 0;
|
||||||
|
QDateTime m_lastSeen;
|
||||||
|
|
||||||
// Node information
|
// Node information
|
||||||
ZigbeeDeviceProfile::NodeDescriptor m_nodeDescriptor;
|
ZigbeeDeviceProfile::NodeDescriptor m_nodeDescriptor;
|
||||||
@ -122,6 +125,7 @@ signals:
|
|||||||
void nodeInitializationFailed();
|
void nodeInitializationFailed();
|
||||||
void stateChanged(State state);
|
void stateChanged(State state);
|
||||||
void lqiChanged(quint8 lqi);
|
void lqiChanged(quint8 lqi);
|
||||||
|
void lastSeenChanged(const QDateTime &lastSeen);
|
||||||
void connectedChanged(bool connected);
|
void connectedChanged(bool connected);
|
||||||
void clusterAdded(ZigbeeCluster *cluster);
|
void clusterAdded(ZigbeeCluster *cluster);
|
||||||
void clusterAttributeChanged(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
void clusterAttributeChanged(ZigbeeCluster *cluster, const ZigbeeClusterAttribute &attribute);
|
||||||
|
|||||||
Reference in New Issue
Block a user