Make node init state more reliable and fix uninitialized node list

pull/6/head
Simon Stürz 2020-03-19 17:26:08 +01:00
parent e6fb4fbd08
commit c2d58a6c8d
6 changed files with 69 additions and 27 deletions

View File

@ -71,7 +71,7 @@ ZigbeeInterfaceReply *ZigbeeBridgeControllerNxp::commandErasePersistantData()
{
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData, QByteArray()));
request.setDescription("Erase persistent data");
request.setTimoutIntervall(5000);
return sendRequest(request);
}

View File

@ -1073,7 +1073,7 @@ void ZigbeeNetworkNxp::startNetwork()
// FIXME: define if router or coordinator
qCDebug(dcZigbeeNetwork()) << "Start network...";
if (state() == StateUninitialized)
if (state() == StateUninitialized && !m_factoryResetting)
loadNetwork();
// 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()
{
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
m_factoryResetting = true;
clearSettings();
setState(StateUninitialized);
m_factoryResetting = true;
qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network.";
startNetwork();
}

View File

@ -73,6 +73,10 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
switch (m_initState) {
case InitStateNone:
m_initStateRetry = 0;
break;
case InitStateError:
break;
case InitStateNodeDescriptor: {
qCDebug(dcZigbeeNode()) << "Request node descriptor for" << this;
@ -82,8 +86,18 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
if (reply->status() != ZigbeeInterfaceReply::Success) {
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());
setInitState(InitStatePowerDescriptor);
});
@ -97,8 +111,19 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
if (reply->status() != ZigbeeInterfaceReply::Success) {
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();
quint8 sequenceNumber = 0;
quint8 status = 0;
@ -119,28 +144,39 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
if (reply->status() != ZigbeeInterfaceReply::Success) {
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
} else {
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);
m_initStateRetry++;
if (m_initStateRetry > 3) {
qCWarning(dcZigbeeNode()) << "Failed to get active endpoints after 3 retries. This node will not be added to the network.";
setInitState(InitStateError);
return;
} else {
setInitState(InitStateActiveEndpoints);
return;
}
}
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);
});
break;
@ -257,9 +293,8 @@ void ZigbeeNodeNxp::setInitState(ZigbeeNodeNxp::InitState initState)
ZigbeeCluster *basicCluster = endpoint->getInputCluster(Zigbee::ClusterIdBasic);
if (!basicCluster) {
qCWarning(dcZigbeeNode()) << "Failed to fetch basic cluster from" << endpoint;
setState(StateInitialized);
return;
qCDebug(dcZigbeeNode()) << "This endpoint has no basic cluster" << endpoint;
continue;
}
m_uninitializedEndpoints.clear();

View File

@ -43,6 +43,7 @@ class ZigbeeNodeNxp : public ZigbeeNode
public:
enum InitState {
InitStateNone,
InitStateError,
InitStateNodeDescriptor,
InitStatePowerDescriptor,
InitStateActiveEndpoints,
@ -58,6 +59,7 @@ public:
private:
ZigbeeBridgeControllerNxp *m_controller = nullptr;
InitState m_initState = InitStateNone;
int m_initStateRetry = 0;
QList<quint8> m_uninitializedEndpoints;
QList<quint16> m_uninitalizedBasicClusterAttributes;

View File

@ -335,7 +335,7 @@ public:
ClusterIdPressureMeasurement = 0x0403,
ClusterIdFlowMeasurement = 0x0404,
ClusterIdRelativeHumidityMeasurement = 0x0405,
ClusterIdOccapancySensing = 0x0406,
ClusterIdOccupancySensing = 0x0406,
// Security and Safty
ClusterIdIasZone = 0x0500,

View File

@ -324,6 +324,11 @@ void ZigbeeNetwork::clearSettings()
removeNode(node);
}
foreach (ZigbeeNode *node, m_uninitializedNodes) {
m_uninitializedNodes.removeAll(node);
node->deleteLater();
}
qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName;
QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
settings.clear();