diff --git a/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp b/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp index 22ad7ce..38c4a2d 100644 --- a/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp +++ b/libnymea-zigbee/nxp/zigbeebridgecontrollernxp.cpp @@ -71,7 +71,7 @@ ZigbeeInterfaceReply *ZigbeeBridgeControllerNxp::commandErasePersistantData() { ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeErasePersistentData, QByteArray())); request.setDescription("Erase persistent data"); - + request.setTimoutIntervall(5000); return sendRequest(request); } diff --git a/libnymea-zigbee/nxp/zigbeenetworknxp.cpp b/libnymea-zigbee/nxp/zigbeenetworknxp.cpp index fb9aa08..81c3984 100644 --- a/libnymea-zigbee/nxp/zigbeenetworknxp.cpp +++ b/libnymea-zigbee/nxp/zigbeenetworknxp.cpp @@ -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(); } diff --git a/libnymea-zigbee/nxp/zigbeenodenxp.cpp b/libnymea-zigbee/nxp/zigbeenodenxp.cpp index 30ad436..a9a0f19 100644 --- a/libnymea-zigbee/nxp/zigbeenodenxp.cpp +++ b/libnymea-zigbee/nxp/zigbeenodenxp.cpp @@ -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(); diff --git a/libnymea-zigbee/nxp/zigbeenodenxp.h b/libnymea-zigbee/nxp/zigbeenodenxp.h index 85c96e4..4b198ac 100644 --- a/libnymea-zigbee/nxp/zigbeenodenxp.h +++ b/libnymea-zigbee/nxp/zigbeenodenxp.h @@ -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 m_uninitializedEndpoints; QList m_uninitalizedBasicClusterAttributes; diff --git a/libnymea-zigbee/zigbee.h b/libnymea-zigbee/zigbee.h index 0170157..99a534f 100644 --- a/libnymea-zigbee/zigbee.h +++ b/libnymea-zigbee/zigbee.h @@ -335,7 +335,7 @@ public: ClusterIdPressureMeasurement = 0x0403, ClusterIdFlowMeasurement = 0x0404, ClusterIdRelativeHumidityMeasurement = 0x0405, - ClusterIdOccapancySensing = 0x0406, + ClusterIdOccupancySensing = 0x0406, // Security and Safty ClusterIdIasZone = 0x0500, diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index 65ae72d..7abe63e 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -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();