From 5c3470e9d3da986a04abf8fe48f3d73e24538623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 16 Nov 2020 12:11:35 +0100 Subject: [PATCH] Update out of spec cluster handling and fix debian control --- debian/control | 5 +++-- docs/{ => deconz}/deCONZ-BHB-en.pdf | Bin .../{ => deconz}/deCONZ-Serial-Protocol-en.pdf | Bin ...-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf | Bin ...T-Gateway-Control-Bridge-UserGuide-1014.pdf | Bin .../JN-UG-3076 - Zigbee Homeautomation.pdf | Bin .../JN-UG-3091 - Zigbee Light Link.pdf | Bin docs/{ => nxp}/JN-UG-3113.pdf | Bin .../zcl/lighting/zigbeeclustercolorcontrol.cpp | 17 +++++++++++++++++ .../zcl/lighting/zigbeeclustercolorcontrol.h | 3 +++ libnymea-zigbee/zigbeenetwork.cpp | 7 +++++++ libnymea-zigbee/zigbeenetwork.h | 2 +- libnymea-zigbee/zigbeenetworkdatabase.cpp | 4 ++++ libnymea-zigbee/zigbeenode.cpp | 7 ++++++- libnymea-zigbee/zigbeenodeendpoint.cpp | 8 ++++++++ 15 files changed, 49 insertions(+), 4 deletions(-) rename docs/{ => deconz}/deCONZ-BHB-en.pdf (100%) rename docs/{ => deconz}/deCONZ-Serial-Protocol-en.pdf (100%) rename docs/{ => nxp}/JN-AN-1216-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf (100%) rename docs/{ => nxp}/JN-AN-1223-ZigBee-IoT-Gateway-Control-Bridge-UserGuide-1014.pdf (100%) rename docs/{ => nxp}/JN-UG-3076 - Zigbee Homeautomation.pdf (100%) rename docs/{ => nxp}/JN-UG-3091 - Zigbee Light Link.pdf (100%) rename docs/{ => nxp}/JN-UG-3113.pdf (100%) diff --git a/debian/control b/debian/control index c54cca0..24704d0 100644 --- a/debian/control +++ b/debian/control @@ -22,7 +22,8 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, libqt5network5, libqt5gui5, - libqt5serialport5 + libqt5serialport5, + libqt5sql5-sqlite Description: Qt 5 based library for ZigBee Qt 5 based library for ZigBee. @@ -34,5 +35,5 @@ Depends: libnymea-zigbee1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, pkg-config -Dscription: Qt 5 based library for ZigBee - development files +Description: Qt 5 based library for ZigBee - development files Development files for Qt 5 based ZigBee library. diff --git a/docs/deCONZ-BHB-en.pdf b/docs/deconz/deCONZ-BHB-en.pdf similarity index 100% rename from docs/deCONZ-BHB-en.pdf rename to docs/deconz/deCONZ-BHB-en.pdf diff --git a/docs/deCONZ-Serial-Protocol-en.pdf b/docs/deconz/deCONZ-Serial-Protocol-en.pdf similarity index 100% rename from docs/deCONZ-Serial-Protocol-en.pdf rename to docs/deconz/deCONZ-Serial-Protocol-en.pdf diff --git a/docs/JN-AN-1216-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf b/docs/nxp/JN-AN-1216-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf similarity index 100% rename from docs/JN-AN-1216-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf rename to docs/nxp/JN-AN-1216-ZigBee-3-0-IoT-ControlBridge-UserGuide.pdf diff --git a/docs/JN-AN-1223-ZigBee-IoT-Gateway-Control-Bridge-UserGuide-1014.pdf b/docs/nxp/JN-AN-1223-ZigBee-IoT-Gateway-Control-Bridge-UserGuide-1014.pdf similarity index 100% rename from docs/JN-AN-1223-ZigBee-IoT-Gateway-Control-Bridge-UserGuide-1014.pdf rename to docs/nxp/JN-AN-1223-ZigBee-IoT-Gateway-Control-Bridge-UserGuide-1014.pdf diff --git a/docs/JN-UG-3076 - Zigbee Homeautomation.pdf b/docs/nxp/JN-UG-3076 - Zigbee Homeautomation.pdf similarity index 100% rename from docs/JN-UG-3076 - Zigbee Homeautomation.pdf rename to docs/nxp/JN-UG-3076 - Zigbee Homeautomation.pdf diff --git a/docs/JN-UG-3091 - Zigbee Light Link.pdf b/docs/nxp/JN-UG-3091 - Zigbee Light Link.pdf similarity index 100% rename from docs/JN-UG-3091 - Zigbee Light Link.pdf rename to docs/nxp/JN-UG-3091 - Zigbee Light Link.pdf diff --git a/docs/JN-UG-3113.pdf b/docs/nxp/JN-UG-3113.pdf similarity index 100% rename from docs/JN-UG-3113.pdf rename to docs/nxp/JN-UG-3113.pdf diff --git a/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.cpp b/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.cpp index d0017be..9300d89 100644 --- a/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.cpp +++ b/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.cpp @@ -218,6 +218,11 @@ quint16 ZigbeeClusterColorControl::colorTemperatureMireds() const return m_colorTemperatureMireds; } +ZigbeeClusterColorControl::ColorCapabilities ZigbeeClusterColorControl::colorCapabilities() const +{ + return m_colorCapabilities; +} + void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attribute) { qCDebug(dcZigbeeCluster()) << "Attribute changed" << m_node << m_endpoint << this << static_cast(attribute.id()) << attribute.dataType(); @@ -236,6 +241,18 @@ void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attri } break; } + case AttributeColorCapabilities: { + bool valueOk = false; + quint16 value = attribute.dataType().toUInt16(&valueOk); + if (valueOk) { + m_colorCapabilities = static_cast(value); + qCDebug(dcZigbeeCluster()) << "Color capabilities changed on" << m_node << m_endpoint << this << m_colorCapabilities; + emit colorCapabilitiesChanged(m_colorCapabilities); + } else { + qCWarning(dcZigbeeCluster()) << "Failed to parse attribute data" << m_node << m_endpoint << this << attribute; + } + break; + } default: break; } diff --git a/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.h b/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.h index 26d3d9c..9611bc4 100644 --- a/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.h +++ b/libnymea-zigbee/zcl/lighting/zigbeeclustercolorcontrol.h @@ -232,12 +232,15 @@ public: ZigbeeClusterReply *commandStepColorTemperature(StepMode stepMode, quint16 stepSize, quint16 transitionTime, quint16 minColorTemperature, quint16 maxColorTemperature); quint16 colorTemperatureMireds() const; + ColorCapabilities colorCapabilities() const; signals: void colorTemperatureMiredsChanged(quint16 colorTemperatureMireds); + void colorCapabilitiesChanged(ColorCapabilities colorCapabilities); private: quint16 m_colorTemperatureMireds = 0; + ColorCapabilities m_colorCapabilities = ColorCapabilities(); void setAttribute(const ZigbeeClusterAttribute &attribute) override; diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index 82a7b6f..a2502e1 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -393,6 +393,13 @@ void ZigbeeNetwork::addNodeInternally(ZigbeeNode *node) m_database->updateNodeLastSeen(node, lastSeen); }); + connect(node, &ZigbeeNode::clusterAdded, this, [this, node](ZigbeeCluster *cluster){ + if (node->state() == ZigbeeNode::StateInitialized) { + qCWarning(dcZigbeeNetwork()) << node << cluster << "cluster added but the node has already been initialized. This node is out of spec. Save the node nether the less..."; + m_database->saveNode(node); + } + }); + // Note: if a cluster shows up after initialization (out of spec devices), save the cluster and it's attributes foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) { connect(endpoint, &ZigbeeNodeEndpoint::clusterAttributeChanged, this, &ZigbeeNetwork::onNodeClusterAttributeChanged); diff --git a/libnymea-zigbee/zigbeenetwork.h b/libnymea-zigbee/zigbeenetwork.h index 2f1009e..527a77c 100644 --- a/libnymea-zigbee/zigbeenetwork.h +++ b/libnymea-zigbee/zigbeenetwork.h @@ -37,8 +37,8 @@ #include "zigbeechannelmask.h" #include "zigbeesecurityconfiguration.h" -class ZigbeeBridgeController; class ZigbeeNetworkDatabase; +class ZigbeeBridgeController; class ZigbeeNetwork : public QObject { diff --git a/libnymea-zigbee/zigbeenetworkdatabase.cpp b/libnymea-zigbee/zigbeenetworkdatabase.cpp index 6308c99..6e63e7f 100644 --- a/libnymea-zigbee/zigbeenetworkdatabase.cpp +++ b/libnymea-zigbee/zigbeenetworkdatabase.cpp @@ -167,6 +167,10 @@ QList ZigbeeNetworkDatabase::loadNodes() } node->m_endpoints.append(endpoint); + + // Connect after initialization for out of spec nodes + connect(endpoint, &ZigbeeNodeEndpoint::inputClusterAdded, node, &ZigbeeNode::clusterAdded); + connect(endpoint, &ZigbeeNodeEndpoint::outputClusterAdded, node, &ZigbeeNode::clusterAdded); } nodes.append(node); } diff --git a/libnymea-zigbee/zigbeenode.cpp b/libnymea-zigbee/zigbeenode.cpp index 48cac83..1182017 100644 --- a/libnymea-zigbee/zigbeenode.cpp +++ b/libnymea-zigbee/zigbeenode.cpp @@ -168,7 +168,8 @@ void ZigbeeNode::initNodeDescriptor() } else { qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up."; m_requestRetry = 0; - emit nodeInitializationFailed(); + qCWarning(dcZigbeeNode()) << this << "is out of spec. A device must implement the node descriptor. Continue anyways with the power decriptor..."; + initPowerDescriptor(); } return; } @@ -374,6 +375,10 @@ void ZigbeeNode::initEndpoint(quint8 endpointId) m_uninitializedEndpoints.removeAll(endpointId); endpoint->m_initialized = true; + // Connect after initialization for out of spec nodes + connect(endpoint, &ZigbeeNodeEndpoint::inputClusterAdded, this, &ZigbeeNode::clusterAdded); + connect(endpoint, &ZigbeeNodeEndpoint::outputClusterAdded, this, &ZigbeeNode::clusterAdded); + if (m_uninitializedEndpoints.isEmpty()) { // Note: if we are initializing the coordinator, we can stop here if (m_shortAddress == 0) { diff --git a/libnymea-zigbee/zigbeenodeendpoint.cpp b/libnymea-zigbee/zigbeenodeendpoint.cpp index f09491f..87516fa 100644 --- a/libnymea-zigbee/zigbeenodeendpoint.cpp +++ b/libnymea-zigbee/zigbeenodeendpoint.cpp @@ -256,7 +256,15 @@ void ZigbeeNodeEndpoint::handleZigbeeClusterLibraryIndication(const Zigbee::Apsd if (!cluster) { cluster = createCluster(static_cast(indication.clusterId), ZigbeeCluster::Client); qCDebug(dcZigbeeEndpoint()) << "Received a ZCL indication for a client cluster which does not exist yet on" << m_node << this << "Creating" << cluster; + addOutputCluster(cluster); + if (m_initialized) { + // Note: if the node has already been initialized and the cluster did not exist until now, + // we need to store the new cluster in the database before updating the attribute. This is required + // only for devices which are out of spec and do not list the new cluster in the simple descriptor. + + + } } break; case ZigbeeClusterLibrary::DirectionServerToClient: