From 71675df1c72aaf8ecdc2ef405b63d5fb77063b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sat, 30 May 2020 10:57:41 +0200 Subject: [PATCH] Improve IAS zone cluster attribute updating and implement generic cluster attribute changed signal for endpoints --- .../zcl/security/zigbeeclusteriaszone.cpp | 13 ++++-- .../zcl/security/zigbeeclusteriaszone.h | 44 +++++++++---------- libnymea-zigbee/zigbeedatatype.cpp | 2 +- libnymea-zigbee/zigbeenodeendpoint.cpp | 6 +++ 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.cpp b/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.cpp index 7afd29e..5695653 100644 --- a/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.cpp +++ b/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.cpp @@ -66,10 +66,10 @@ void ZigbeeClusterIasZone::processDataIndication(ZigbeeClusterLibrary::Frame fra // If the client cluster sends data to a server cluster (independent which), the command was executed on the device like button pressed if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionServerToClient) { // Read the payload which is - ClientCommand command = static_cast(frame.header.command); + ServerCommand command = static_cast(frame.header.command); qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command; switch (command) { - case ClientCommandStatusChangedNotification: { + case ServerCommandStatusChangedNotification: { QDataStream stream(frame.payload); stream.setByteOrder(QDataStream::LittleEndian); quint16 zoneStatus = 0; quint8 extendedStatus = 0; quint8 zoneId = 0xff; quint16 delay = 0; @@ -77,10 +77,14 @@ void ZigbeeClusterIasZone::processDataIndication(ZigbeeClusterLibrary::Frame fra qCDebug(dcZigbeeCluster()) << "IAS zone status notification from" << m_node << m_endpoint << this << ZoneStatusFlags(zoneStatus) << "Extended status:" << ZigbeeUtils::convertByteToHexString(extendedStatus) << "Zone ID:" << ZigbeeUtils::convertByteToHexString(zoneId) << "Delay:" << delay << "[s/4]"; + + // Update the ZoneState attribute + setAttribute(ZigbeeClusterAttribute(AttributeZoneState, ZigbeeDataType(Zigbee::BitMap16, frame.payload.left(2)))); + emit zoneStatusChanged(ZoneStatusFlags(zoneStatus), extendedStatus, zoneId, delay); break; } - case ClientCommandZoneEnrollRequest: { + case ServerCommandZoneEnrollRequest: { QDataStream stream(frame.payload); stream.setByteOrder(QDataStream::LittleEndian); quint16 zoneTypeInt = 0; quint16 manufacturerCode = 0; @@ -88,6 +92,9 @@ void ZigbeeClusterIasZone::processDataIndication(ZigbeeClusterLibrary::Frame fra ZoneType zoneType = static_cast(zoneTypeInt); qCDebug(dcZigbeeCluster()) << "IAS zone enroll request from" << m_node << m_endpoint << this << zoneType << "Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode); + // Update the ZoneState attribute + setAttribute(ZigbeeClusterAttribute(AttributeZoneType, ZigbeeDataType(Zigbee::Enum16, frame.payload.left(2)))); + emit zoneEnrollRequest(zoneType, manufacturerCode); break; } diff --git a/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.h b/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.h index 6650581..9a38663 100644 --- a/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.h +++ b/libnymea-zigbee/zcl/security/zigbeeclusteriaszone.h @@ -85,20 +85,20 @@ public: }; Q_ENUM(ZoneType) - enum ZoneStatusFlag { - ZoneStatusFlagAlarm1 = 0x0001, - ZoneStatusFlagAlarm2 = 0x0002, - ZoneStatusFlagTamper = 0x0004, - ZoneStatusFlagBattery = 0x0008, - ZoneStatusFlagSupervisionReports = 0x0010, - ZoneStatusFlagRestoreReports = 0x0020, - ZoneStatusFlagTrouble = 0x0040, - ZoneStatusFlagAcMains = 0x0080, - ZoneStatusFlagTest = 0x0100, - ZoneStatusFlagBatteryDefect = 0x0200 + enum ZoneStatus { + ZoneStatusAlarm1 = 0x0001, + ZoneStatusAlarm2 = 0x0002, + ZoneStatusTamper = 0x0004, + ZoneStatusBattery = 0x0008, + ZoneStatusSupervisionReports = 0x0010, + ZoneStatusRestoreReports = 0x0020, + ZoneStatusTrouble = 0x0040, + ZoneStatusAcMains = 0x0080, + ZoneStatusTest = 0x0100, + ZoneStatusBatteryDefect = 0x0200 }; - Q_ENUM(ZoneStatusFlag) - Q_DECLARE_FLAGS(ZoneStatusFlags, ZoneStatusFlag) + Q_ENUM(ZoneStatus) + Q_DECLARE_FLAGS(ZoneStatusFlags, ZoneStatus) enum EnrollResponseCode { EnrollResponseCodeSuccess = 0x00, @@ -108,19 +108,19 @@ public: }; Q_ENUM(EnrollResponseCode) - enum ClientCommand { - ClientCommandStatusChangedNotification = 0x00, // M - ClientCommandZoneEnrollRequest = 0x01 // M - }; - Q_ENUM(ClientCommand) - enum ServerCommand { - ServerCommandEnrollResponse = 0x00, // M - ServerCommandInitNormalOperationMode = 0x01, // O - ServerCommandInitTestMode = 0x02 // O + ServerCommandStatusChangedNotification = 0x00, // M + ServerCommandZoneEnrollRequest = 0x01 // M }; Q_ENUM(ServerCommand) + enum ClientCommand { + ClientCommandEnrollResponse = 0x00, // M + ClientCommandInitNormalOperationMode = 0x01, // O + ClientCommandInitTestMode = 0x02 // O + }; + Q_ENUM(ClientCommand) + explicit ZigbeeClusterIasZone(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); // TODO: write server commands diff --git a/libnymea-zigbee/zigbeedatatype.cpp b/libnymea-zigbee/zigbeedatatype.cpp index 005c463..0b7e664 100644 --- a/libnymea-zigbee/zigbeedatatype.cpp +++ b/libnymea-zigbee/zigbeedatatype.cpp @@ -317,7 +317,7 @@ quint16 ZigbeeDataType::toUInt16(bool *ok) const if (ok) *ok = true; quint16 value = 0; - if (m_data.count() != 2 || m_dataType != Zigbee::Uint16) { + if (m_data.count() != 2) { if (ok) *ok = false; return value; } diff --git a/libnymea-zigbee/zigbeenodeendpoint.cpp b/libnymea-zigbee/zigbeenodeendpoint.cpp index bdd3fdf..348d41d 100644 --- a/libnymea-zigbee/zigbeenodeendpoint.cpp +++ b/libnymea-zigbee/zigbeenodeendpoint.cpp @@ -202,12 +202,18 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(Zigbee::ClusterId clusterId, Zi void ZigbeeNodeEndpoint::addInputCluster(ZigbeeCluster *cluster) { m_inputClusters.insert(cluster->clusterId(), cluster); + connect(cluster, &ZigbeeCluster::attributeChanged, this, [this, cluster](const ZigbeeClusterAttribute &attribute){ + emit clusterAttributeChanged(cluster, attribute); + }); emit inputClusterAdded(cluster); } void ZigbeeNodeEndpoint::addOutputCluster(ZigbeeCluster *cluster) { m_outputClusters.insert(cluster->clusterId(), cluster); + connect(cluster, &ZigbeeCluster::attributeChanged, this, [this, cluster](const ZigbeeClusterAttribute &attribute){ + emit clusterAttributeChanged(cluster, attribute); + }); emit outputClusterAdded(cluster); }