Make node init state more reliable and fix uninitialized node list
This commit is contained in:
parent
e6fb4fbd08
commit
c2d58a6c8d
@ -71,7 +71,7 @@ ZigbeeInterfaceReply *ZigbeeBridgeControllerNxp::commandErasePersistantData()
|
|||||||
{
|
{
|
||||||
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData, QByteArray()));
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData, QByteArray()));
|
||||||
request.setDescription("Erase persistent data");
|
request.setDescription("Erase persistent data");
|
||||||
|
request.setTimoutIntervall(5000);
|
||||||
return sendRequest(request);
|
return sendRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1073,7 +1073,7 @@ void ZigbeeNetworkNxp::startNetwork()
|
|||||||
// FIXME: define if router or coordinator
|
// FIXME: define if router or coordinator
|
||||||
qCDebug(dcZigbeeNetwork()) << "Start network...";
|
qCDebug(dcZigbeeNetwork()) << "Start network...";
|
||||||
|
|
||||||
if (state() == StateUninitialized)
|
if (state() == StateUninitialized && !m_factoryResetting)
|
||||||
loadNetwork();
|
loadNetwork();
|
||||||
|
|
||||||
// Do a factory reset if there are no network configuration and create a new one from scratch
|
// Do a factory reset if there are no network configuration and create a new one from scratch
|
||||||
@ -1150,9 +1150,9 @@ void ZigbeeNetworkNxp::reset()
|
|||||||
void ZigbeeNetworkNxp::factoryResetNetwork()
|
void ZigbeeNetworkNxp::factoryResetNetwork()
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
|
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
|
||||||
m_factoryResetting = true;
|
|
||||||
clearSettings();
|
clearSettings();
|
||||||
setState(StateUninitialized);
|
setState(StateUninitialized);
|
||||||
|
m_factoryResetting = true;
|
||||||
qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network.";
|
qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network.";
|
||||||
startNetwork();
|
startNetwork();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,6 +73,10 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
|
|||||||
|
|
||||||
switch (m_initState) {
|
switch (m_initState) {
|
||||||
case InitStateNone:
|
case InitStateNone:
|
||||||
|
m_initStateRetry = 0;
|
||||||
|
break;
|
||||||
|
case InitStateError:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case InitStateNodeDescriptor: {
|
case InitStateNodeDescriptor: {
|
||||||
qCDebug(dcZigbeeNode()) << "Request node descriptor for" << this;
|
qCDebug(dcZigbeeNode()) << "Request node descriptor for" << this;
|
||||||
@ -82,8 +86,18 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
|
|||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
|
m_initStateRetry++;
|
||||||
|
if (m_initStateRetry > 3) {
|
||||||
|
qCWarning(dcZigbeeNode()) << "Failed to get node descriptor after 3 retries. This node will not be added to the network.";
|
||||||
|
setInitState(InitStateError);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
setInitState(InitStateNodeDescriptor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_initStateRetry = 0;
|
||||||
setNodeDescriptorRawData(reply->additionalMessage().data());
|
setNodeDescriptorRawData(reply->additionalMessage().data());
|
||||||
setInitState(InitStatePowerDescriptor);
|
setInitState(InitStatePowerDescriptor);
|
||||||
});
|
});
|
||||||
@ -97,8 +111,19 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
|
|||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
|
m_initStateRetry++;
|
||||||
|
if (m_initStateRetry > 3) {
|
||||||
|
qCWarning(dcZigbeeNode()) << "Failed to get power descriptor after 3 retries. This node will not be added to the network.";
|
||||||
|
setInitState(InitStateError);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
setInitState(InitStatePowerDescriptor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_initStateRetry = 0;
|
||||||
|
|
||||||
QByteArray data = reply->additionalMessage().data();
|
QByteArray data = reply->additionalMessage().data();
|
||||||
quint8 sequenceNumber = 0;
|
quint8 sequenceNumber = 0;
|
||||||
quint8 status = 0;
|
quint8 status = 0;
|
||||||
@ -119,28 +144,39 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
|
|||||||
|
|
||||||
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
} else {
|
m_initStateRetry++;
|
||||||
QByteArray data = reply->additionalMessage().data();
|
if (m_initStateRetry > 3) {
|
||||||
quint8 sequenceNumber = 0;
|
qCWarning(dcZigbeeNode()) << "Failed to get active endpoints after 3 retries. This node will not be added to the network.";
|
||||||
quint8 status = 0;
|
setInitState(InitStateError);
|
||||||
quint16 shortAddress = 0;
|
return;
|
||||||
quint8 endpointCount = 0;
|
} else {
|
||||||
|
setInitState(InitStateActiveEndpoints);
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
return;
|
||||||
stream >> sequenceNumber >> status >> shortAddress >> endpointCount;
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << "Active endpoint list received:";
|
|
||||||
qCDebug(dcZigbeeNode()) << "Sequence number" << sequenceNumber;
|
|
||||||
qCDebug(dcZigbeeNode()) << "Status:" << status;
|
|
||||||
qCDebug(dcZigbeeNode()) << "Short address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
|
|
||||||
qCDebug(dcZigbeeNode()) << "Endpoint count:" << endpointCount;
|
|
||||||
for (int i = 0; i < endpointCount; i++) {
|
|
||||||
quint8 endpointId = 0;
|
|
||||||
stream >> endpointId;
|
|
||||||
m_uninitializedEndpoints.append(endpointId);
|
|
||||||
qCDebug(dcZigbeeNode()) << " - " << ZigbeeUtils::convertByteToHexString(endpointId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_initStateRetry = 0;
|
||||||
|
|
||||||
|
QByteArray data = reply->additionalMessage().data();
|
||||||
|
quint8 sequenceNumber = 0;
|
||||||
|
quint8 status = 0;
|
||||||
|
quint16 shortAddress = 0;
|
||||||
|
quint8 endpointCount = 0;
|
||||||
|
|
||||||
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
|
stream >> sequenceNumber >> status >> shortAddress >> endpointCount;
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNode()) << "Active endpoint list received:";
|
||||||
|
qCDebug(dcZigbeeNode()) << "Sequence number" << sequenceNumber;
|
||||||
|
qCDebug(dcZigbeeNode()) << "Status:" << status;
|
||||||
|
qCDebug(dcZigbeeNode()) << "Short address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
|
||||||
|
qCDebug(dcZigbeeNode()) << "Endpoint count:" << endpointCount;
|
||||||
|
for (int i = 0; i < endpointCount; i++) {
|
||||||
|
quint8 endpointId = 0;
|
||||||
|
stream >> endpointId;
|
||||||
|
m_uninitializedEndpoints.append(endpointId);
|
||||||
|
qCDebug(dcZigbeeNode()) << " - " << ZigbeeUtils::convertByteToHexString(endpointId);
|
||||||
|
}
|
||||||
setInitState(InitStateSimpleDescriptors);
|
setInitState(InitStateSimpleDescriptors);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -257,9 +293,8 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
|
|||||||
|
|
||||||
ZigbeeCluster *basicCluster = endpoint->getInputCluster(Zigbee::ClusterIdBasic);
|
ZigbeeCluster *basicCluster = endpoint->getInputCluster(Zigbee::ClusterIdBasic);
|
||||||
if (!basicCluster) {
|
if (!basicCluster) {
|
||||||
qCWarning(dcZigbeeNode()) << "Failed to fetch basic cluster from" << endpoint;
|
qCDebug(dcZigbeeNode()) << "This endpoint has no basic cluster" << endpoint;
|
||||||
setState(StateInitialized);
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_uninitializedEndpoints.clear();
|
m_uninitializedEndpoints.clear();
|
||||||
|
|||||||
@ -43,6 +43,7 @@ class ZigbeeNodeNxp : public ZigbeeNode
|
|||||||
public:
|
public:
|
||||||
enum InitState {
|
enum InitState {
|
||||||
InitStateNone,
|
InitStateNone,
|
||||||
|
InitStateError,
|
||||||
InitStateNodeDescriptor,
|
InitStateNodeDescriptor,
|
||||||
InitStatePowerDescriptor,
|
InitStatePowerDescriptor,
|
||||||
InitStateActiveEndpoints,
|
InitStateActiveEndpoints,
|
||||||
@ -58,6 +59,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
||||||
InitState m_initState = InitStateNone;
|
InitState m_initState = InitStateNone;
|
||||||
|
int m_initStateRetry = 0;
|
||||||
|
|
||||||
QList<quint8> m_uninitializedEndpoints;
|
QList<quint8> m_uninitializedEndpoints;
|
||||||
QList<quint16> m_uninitalizedBasicClusterAttributes;
|
QList<quint16> m_uninitalizedBasicClusterAttributes;
|
||||||
|
|||||||
@ -335,7 +335,7 @@ public:
|
|||||||
ClusterIdPressureMeasurement = 0x0403,
|
ClusterIdPressureMeasurement = 0x0403,
|
||||||
ClusterIdFlowMeasurement = 0x0404,
|
ClusterIdFlowMeasurement = 0x0404,
|
||||||
ClusterIdRelativeHumidityMeasurement = 0x0405,
|
ClusterIdRelativeHumidityMeasurement = 0x0405,
|
||||||
ClusterIdOccapancySensing = 0x0406,
|
ClusterIdOccupancySensing = 0x0406,
|
||||||
|
|
||||||
// Security and Safty
|
// Security and Safty
|
||||||
ClusterIdIasZone = 0x0500,
|
ClusterIdIasZone = 0x0500,
|
||||||
|
|||||||
@ -324,6 +324,11 @@ void ZigbeeNetwork::clearSettings()
|
|||||||
removeNode(node);
|
removeNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (ZigbeeNode *node, m_uninitializedNodes) {
|
||||||
|
m_uninitializedNodes.removeAll(node);
|
||||||
|
node->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName;
|
qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName;
|
||||||
QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
|
QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
|
||||||
settings.clear();
|
settings.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user