From c565a25be255e6515fc9de2c433ce6ffd236486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 29 May 2020 16:23:09 +0200 Subject: [PATCH] Fix endpoint initialization order and move back to sorted list --- .../zcl/general/zigbeeclusteridentify.h | 2 ++ .../zcl/general/zigbeeclusteronoff.cpp | 10 ++++++ .../zcl/general/zigbeeclusteronoff.h | 5 ++- libnymea-zigbee/zigbeenetwork.cpp | 2 +- libnymea-zigbee/zigbeenode.cpp | 34 +++++++++++++++---- libnymea-zigbee/zigbeenode.h | 2 +- 6 files changed, 45 insertions(+), 10 deletions(-) diff --git a/libnymea-zigbee/zcl/general/zigbeeclusteridentify.h b/libnymea-zigbee/zcl/general/zigbeeclusteridentify.h index 4d08fa6..bb2cf2f 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusteridentify.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusteridentify.h @@ -81,6 +81,8 @@ private: protected: void processDataIndication(ZigbeeClusterLibrary::Frame frame) override; + // TODO: identifyQueryResponse signal + }; #endif // ZIGBEECLUSTERIDENTIFY_H diff --git a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp index 8398abb..76b7760 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp +++ b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp @@ -198,6 +198,16 @@ void ZigbeeClusterOnOff::setAttribute(const ZigbeeClusterAttribute &attribute) m_attributes.insert(attribute.id(), attribute); emit attributeChanged(attribute); } + + // Parse the information for convinience + if (attribute.id() == AttributeOnOff) { + bool valueOk = false; + bool value = attribute.dataType().toBool(&valueOk); + if (valueOk) { + qCDebug(dcZigbeeCluster()) << "OnOff state changed on" << m_node << m_endpoint << this << value; + emit powerChanged(value); + } + } } void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame) diff --git a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h index 2d269df..f9dc783 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h @@ -80,7 +80,10 @@ protected: void processDataIndication(ZigbeeClusterLibrary::Frame frame) override; signals: - // Note: these signals will only be emitted if the cluster is a client + // Server cluster signals + void powerChanged(bool power); + + // Client cluster signals void commandSent(Command command); }; diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index 64c964d..52f8307 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -365,7 +365,7 @@ void ZigbeeNetwork::loadNetwork() } settings.endArray(); // outputClusters - node->m_endpoints.insert(endpoint->endpointId(), endpoint); + node->m_endpoints.append(endpoint); } settings.endArray(); // endpoints diff --git a/libnymea-zigbee/zigbeenode.cpp b/libnymea-zigbee/zigbeenode.cpp index 4cfc1e4..0fa7b3f 100644 --- a/libnymea-zigbee/zigbeenode.cpp +++ b/libnymea-zigbee/zigbeenode.cpp @@ -68,17 +68,23 @@ ZigbeeAddress ZigbeeNode::extendedAddress() const QList ZigbeeNode::endpoints() const { - return m_endpoints.values(); + return m_endpoints; } bool ZigbeeNode::hasEndpoint(quint8 endpointId) const { - return m_endpoints.keys().contains(endpointId); + return getEndpoint(endpointId) != nullptr; } ZigbeeNodeEndpoint *ZigbeeNode::getEndpoint(quint8 endpointId) const { - return m_endpoints.value(endpointId); + foreach (ZigbeeNodeEndpoint *ep, m_endpoints) { + if (ep->endpointId()== endpointId) { + return ep; + } + } + + return nullptr; } ZigbeeNode::NodeType ZigbeeNode::nodeType() const @@ -635,7 +641,7 @@ void ZigbeeNode::initEndpoint(quint8 endpointId) ZigbeeNodeEndpoint *endpoint = nullptr; if (!hasEndpoint(endpointId)) { endpoint = new ZigbeeNodeEndpoint(m_network, this, endpointId, this); - m_endpoints.insert(endpoint->endpointId(), endpoint); + m_endpoints.append(endpoint); } else { endpoint = getEndpoint(endpointId); } @@ -687,8 +693,22 @@ void ZigbeeNode::initEndpoint(quint8 endpointId) void ZigbeeNode::initBasicCluster() { - // FIXME: check if we want to read from all endpoints the basic cluster information or only from the first - ZigbeeClusterBasic *basicCluster = endpoints().first()->inputCluster(Zigbee::ClusterIdBasic); + // Get the first endpoint which implements the basic cluster + ZigbeeNodeEndpoint *endpoint = nullptr; + foreach (ZigbeeNodeEndpoint *ep, endpoints()) { + if (ep->hasInputCluster(Zigbee::ClusterIdBasic)) { + endpoint = ep; + break; + } + } + + if (!endpoint) { + qCWarning(dcZigbeeNode()) << "Could not find any endpoint contiaining the basic cluster on" << this << "Set the node to initialized anyways."; + setState(StateInitialized); + return; + } + + ZigbeeClusterBasic *basicCluster = endpoint->inputCluster(Zigbee::ClusterIdBasic); if (!basicCluster) { qCWarning(dcZigbeeNode()) << "Could not find basic cluster on" << this << "Set the node to initialized anyways."; // Set the device initialized any ways since this ist just for convinience @@ -839,7 +859,7 @@ void ZigbeeNode::handleZigbeeClusterLibraryIndication(const Zigbee::ApsdeDataInd endpoint = new ZigbeeNodeEndpoint(m_network, this, indication.sourceEndpoint, this); endpoint->setProfile(static_cast(indication.profileId)); // Note: the endpoint is not initializd yet, but keep it anyways - m_endpoints.insert(endpoint->endpointId(), endpoint); + m_endpoints.append(endpoint); } endpoint->handleZigbeeClusterLibraryIndication(indication); diff --git a/libnymea-zigbee/zigbeenode.h b/libnymea-zigbee/zigbeenode.h index fadf600..88a91ef 100644 --- a/libnymea-zigbee/zigbeenode.h +++ b/libnymea-zigbee/zigbeenode.h @@ -199,7 +199,7 @@ private: ZigbeeNetwork *m_network; ZigbeeDeviceObject *m_deviceObject = nullptr; - QHash m_endpoints; + QList m_endpoints; // Node descriptor information QByteArray m_nodeDescriptorRawData;