Improve IAS zone cluster attribute updating and implement generic cluster attribute changed signal for endpoints

This commit is contained in:
Simon Stürz 2020-05-30 10:57:41 +02:00
parent 67c07f674c
commit 71675df1c7
4 changed files with 39 additions and 26 deletions

View File

@ -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 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) { if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionServerToClient) {
// Read the payload which is // Read the payload which is
ClientCommand command = static_cast<ClientCommand>(frame.header.command); ServerCommand command = static_cast<ServerCommand>(frame.header.command);
qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command; qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command;
switch (command) { switch (command) {
case ClientCommandStatusChangedNotification: { case ServerCommandStatusChangedNotification: {
QDataStream stream(frame.payload); QDataStream stream(frame.payload);
stream.setByteOrder(QDataStream::LittleEndian); stream.setByteOrder(QDataStream::LittleEndian);
quint16 zoneStatus = 0; quint8 extendedStatus = 0; quint8 zoneId = 0xff; quint16 delay = 0; 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 qCDebug(dcZigbeeCluster()) << "IAS zone status notification from" << m_node << m_endpoint << this
<< ZoneStatusFlags(zoneStatus) << "Extended status:" << ZigbeeUtils::convertByteToHexString(extendedStatus) << ZoneStatusFlags(zoneStatus) << "Extended status:" << ZigbeeUtils::convertByteToHexString(extendedStatus)
<< "Zone ID:" << ZigbeeUtils::convertByteToHexString(zoneId) << "Delay:" << delay << "[s/4]"; << "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); emit zoneStatusChanged(ZoneStatusFlags(zoneStatus), extendedStatus, zoneId, delay);
break; break;
} }
case ClientCommandZoneEnrollRequest: { case ServerCommandZoneEnrollRequest: {
QDataStream stream(frame.payload); QDataStream stream(frame.payload);
stream.setByteOrder(QDataStream::LittleEndian); stream.setByteOrder(QDataStream::LittleEndian);
quint16 zoneTypeInt = 0; quint16 manufacturerCode = 0; quint16 zoneTypeInt = 0; quint16 manufacturerCode = 0;
@ -88,6 +92,9 @@ void ZigbeeClusterIasZone::processDataIndication(ZigbeeClusterLibrary::Frame fra
ZoneType zoneType = static_cast<ZoneType>(zoneTypeInt); ZoneType zoneType = static_cast<ZoneType>(zoneTypeInt);
qCDebug(dcZigbeeCluster()) << "IAS zone enroll request from" << m_node << m_endpoint << this qCDebug(dcZigbeeCluster()) << "IAS zone enroll request from" << m_node << m_endpoint << this
<< zoneType << "Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode); << zoneType << "Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode);
// Update the ZoneState attribute
setAttribute(ZigbeeClusterAttribute(AttributeZoneType, ZigbeeDataType(Zigbee::Enum16, frame.payload.left(2))));
emit zoneEnrollRequest(zoneType, manufacturerCode); emit zoneEnrollRequest(zoneType, manufacturerCode);
break; break;
} }

View File

@ -85,20 +85,20 @@ public:
}; };
Q_ENUM(ZoneType) Q_ENUM(ZoneType)
enum ZoneStatusFlag { enum ZoneStatus {
ZoneStatusFlagAlarm1 = 0x0001, ZoneStatusAlarm1 = 0x0001,
ZoneStatusFlagAlarm2 = 0x0002, ZoneStatusAlarm2 = 0x0002,
ZoneStatusFlagTamper = 0x0004, ZoneStatusTamper = 0x0004,
ZoneStatusFlagBattery = 0x0008, ZoneStatusBattery = 0x0008,
ZoneStatusFlagSupervisionReports = 0x0010, ZoneStatusSupervisionReports = 0x0010,
ZoneStatusFlagRestoreReports = 0x0020, ZoneStatusRestoreReports = 0x0020,
ZoneStatusFlagTrouble = 0x0040, ZoneStatusTrouble = 0x0040,
ZoneStatusFlagAcMains = 0x0080, ZoneStatusAcMains = 0x0080,
ZoneStatusFlagTest = 0x0100, ZoneStatusTest = 0x0100,
ZoneStatusFlagBatteryDefect = 0x0200 ZoneStatusBatteryDefect = 0x0200
}; };
Q_ENUM(ZoneStatusFlag) Q_ENUM(ZoneStatus)
Q_DECLARE_FLAGS(ZoneStatusFlags, ZoneStatusFlag) Q_DECLARE_FLAGS(ZoneStatusFlags, ZoneStatus)
enum EnrollResponseCode { enum EnrollResponseCode {
EnrollResponseCodeSuccess = 0x00, EnrollResponseCodeSuccess = 0x00,
@ -108,19 +108,19 @@ public:
}; };
Q_ENUM(EnrollResponseCode) Q_ENUM(EnrollResponseCode)
enum ClientCommand {
ClientCommandStatusChangedNotification = 0x00, // M
ClientCommandZoneEnrollRequest = 0x01 // M
};
Q_ENUM(ClientCommand)
enum ServerCommand { enum ServerCommand {
ServerCommandEnrollResponse = 0x00, // M ServerCommandStatusChangedNotification = 0x00, // M
ServerCommandInitNormalOperationMode = 0x01, // O ServerCommandZoneEnrollRequest = 0x01 // M
ServerCommandInitTestMode = 0x02 // O
}; };
Q_ENUM(ServerCommand) 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); explicit ZigbeeClusterIasZone(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
// TODO: write server commands // TODO: write server commands

View File

@ -317,7 +317,7 @@ quint16 ZigbeeDataType::toUInt16(bool *ok) const
if (ok) *ok = true; if (ok) *ok = true;
quint16 value = 0; quint16 value = 0;
if (m_data.count() != 2 || m_dataType != Zigbee::Uint16) { if (m_data.count() != 2) {
if (ok) *ok = false; if (ok) *ok = false;
return value; return value;
} }

View File

@ -202,12 +202,18 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(Zigbee::ClusterId clusterId, Zi
void ZigbeeNodeEndpoint::addInputCluster(ZigbeeCluster *cluster) void ZigbeeNodeEndpoint::addInputCluster(ZigbeeCluster *cluster)
{ {
m_inputClusters.insert(cluster->clusterId(), cluster); m_inputClusters.insert(cluster->clusterId(), cluster);
connect(cluster, &ZigbeeCluster::attributeChanged, this, [this, cluster](const ZigbeeClusterAttribute &attribute){
emit clusterAttributeChanged(cluster, attribute);
});
emit inputClusterAdded(cluster); emit inputClusterAdded(cluster);
} }
void ZigbeeNodeEndpoint::addOutputCluster(ZigbeeCluster *cluster) void ZigbeeNodeEndpoint::addOutputCluster(ZigbeeCluster *cluster)
{ {
m_outputClusters.insert(cluster->clusterId(), cluster); m_outputClusters.insert(cluster->clusterId(), cluster);
connect(cluster, &ZigbeeCluster::attributeChanged, this, [this, cluster](const ZigbeeClusterAttribute &attribute){
emit clusterAttributeChanged(cluster, attribute);
});
emit outputClusterAdded(cluster); emit outputClusterAdded(cluster);
} }