From 5072ad7c1ed04606784b554e7162742804367587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 28 Apr 2021 13:39:07 +0200 Subject: [PATCH] Add develco profile and manufacturer, implement manufacturer specific cluster methods, improve binary input cluster --- .../zcl/general/zigbeeclusterbinaryinput.cpp | 18 +++++++++++++ .../zcl/general/zigbeeclusterbinaryinput.h | 7 ++++++ libnymea-zigbee/zcl/zigbeecluster.cpp | 25 ++++++++++++------- libnymea-zigbee/zcl/zigbeecluster.h | 12 ++++----- libnymea-zigbee/zigbee.h | 2 ++ libnymea-zigbee/zigbeenetwork.cpp | 1 - 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.cpp b/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.cpp index 4450eae..26de8b2 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.cpp +++ b/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.cpp @@ -34,8 +34,26 @@ ZigbeeClusterBinaryInput::ZigbeeClusterBinaryInput(ZigbeeNetwork *network, Zigbe } +bool ZigbeeClusterBinaryInput::presentValue() const +{ + return m_presentValue; +} + void ZigbeeClusterBinaryInput::setAttribute(const ZigbeeClusterAttribute &attribute) { qCDebug(dcZigbeeCluster()) << "Update attribute" << m_node << m_endpoint << this << static_cast(attribute.id()) << attribute.dataType(); updateOrAddAttribute(attribute); + + // Parse the information for convenience + if (attribute.id() == AttributePresentValue) { + bool valueOk = false; + bool value = attribute.dataType().toBool(&valueOk); + if (valueOk) { + m_presentValue = value; + qCDebug(dcZigbeeCluster()) << "Binary input state changed on" << m_node << m_endpoint << this << m_presentValue; + emit presentValueChanged(m_presentValue); + } else { + qCWarning(dcZigbeeCluster()) << "Failed to parse attribute data" << m_node << m_endpoint << this << attribute; + } + } } diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.h b/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.h index 95a2755..d6aeed3 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusterbinaryinput.h @@ -55,7 +55,14 @@ public: explicit ZigbeeClusterBinaryInput(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); + bool presentValue() const; + +signals: + void presentValueChanged(bool presentValue); + private: + bool m_presentValue = false; + void setAttribute(const ZigbeeClusterAttribute &attribute) override; }; diff --git a/libnymea-zigbee/zcl/zigbeecluster.cpp b/libnymea-zigbee/zcl/zigbeecluster.cpp index 80ca4f9..692377a 100644 --- a/libnymea-zigbee/zcl/zigbeecluster.cpp +++ b/libnymea-zigbee/zcl/zigbeecluster.cpp @@ -96,7 +96,7 @@ void ZigbeeCluster::setAttribute(const ZigbeeClusterAttribute &attribute) updateOrAddAttribute(attribute); } -ZigbeeClusterReply *ZigbeeCluster::readAttributes(QList attributes) +ZigbeeClusterReply *ZigbeeCluster::readAttributes(QList attributes, quint16 manufacturerCode) { qCDebug(dcZigbeeCluster()) << "Read attributes from" << m_node << m_endpoint << this << attributes; @@ -108,10 +108,10 @@ ZigbeeClusterReply *ZigbeeCluster::readAttributes(QList attributes) stream << attribute; } - return executeGlobalCommand(ZigbeeClusterLibrary::CommandReadAttributes, payload); + return executeGlobalCommand(ZigbeeClusterLibrary::CommandReadAttributes, payload, manufacturerCode); } -ZigbeeClusterReply *ZigbeeCluster::writeAttributes(QList writeAttributeRecords) +ZigbeeClusterReply *ZigbeeCluster::writeAttributes(QList writeAttributeRecords, quint16 manufacturerCode) { qCDebug(dcZigbeeCluster()) << "Write attributes on" << m_node << m_endpoint << this; QByteArray payload; @@ -119,10 +119,10 @@ ZigbeeClusterReply *ZigbeeCluster::writeAttributes(QList reportingConfigurations) +ZigbeeClusterReply *ZigbeeCluster::configureReporting(QList reportingConfigurations, quint16 manufacturerCode) { qCDebug(dcZigbeeCluster()) << "Configure reporting on" << m_node << m_endpoint << this << reportingConfigurations; @@ -131,11 +131,11 @@ ZigbeeClusterReply *ZigbeeCluster::configureReporting(QList attributes); - ZigbeeClusterReply *writeAttributes(QList writeAttributeRecords); - ZigbeeClusterReply *configureReporting(QList reportingConfigurations); - - - + ZigbeeClusterReply *readAttributes(QList attributes, quint16 manufacturerCode = 0x0000); + ZigbeeClusterReply *writeAttributes(QList writeAttributeRecords, quint16 manufacturerCode = 0x0000); + ZigbeeClusterReply *configureReporting(QList reportingConfigurations, quint16 manufacturerCode = 0x0000); protected: ZigbeeNetwork *m_network = nullptr; @@ -112,7 +109,8 @@ protected: QHash m_pendingReplies; // Global commands - ZigbeeClusterReply *executeGlobalCommand(quint8 command, const QByteArray &payload = QByteArray()); + ZigbeeClusterReply *executeGlobalCommand(quint8 command, const QByteArray &payload = QByteArray(), quint16 manufacturerCode = 0x0000); + ZigbeeClusterReply *executeManufacturerSpecificGlobalCommand(quint8 command, quint16 manufacturerCode, const QByteArray &payload = QByteArray()); // Cluster specific ZigbeeClusterReply *createClusterReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame frame); diff --git a/libnymea-zigbee/zigbee.h b/libnymea-zigbee/zigbee.h index 372c89b..c904184 100644 --- a/libnymea-zigbee/zigbee.h +++ b/libnymea-zigbee/zigbee.h @@ -55,6 +55,7 @@ public: ZigbeeProfilePersonalHomeHospitalCare = 0x0108, ZigbeeProfileAdvancedMetering = 0x0109, ZigbeeProfileLightLink = 0xC05E, + ZigbeeProfileDevelco = 0xC0C9, ZigbeeProfileGreenPower = 0xA1E0 }; Q_ENUM(ZigbeeProfile) @@ -286,6 +287,7 @@ public: Chipcon = 0x1001, Ember = 0x1003, Philips = 0x100b, + Develco = 0x1015, Ikea = 0x117C, FeiBit = 0x117E }; diff --git a/libnymea-zigbee/zigbeenetwork.cpp b/libnymea-zigbee/zigbeenetwork.cpp index d5a0c47..874055b 100644 --- a/libnymea-zigbee/zigbeenetwork.cpp +++ b/libnymea-zigbee/zigbeenetwork.cpp @@ -53,7 +53,6 @@ ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) : } }); - m_reachableRefreshTimer = new QTimer(this); m_reachableRefreshTimer->setInterval(120000); m_reachableRefreshTimer->setSingleShot(false);