Merge PR #57: Implement commands for metering cluster

pull/58/head
jenkins 2022-06-30 15:04:00 +02:00
commit a5d49d7b64
2 changed files with 84 additions and 0 deletions

View File

@ -1,5 +1,6 @@
#include "zigbeeclustermetering.h"
#include <QDataStream>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeCluster)
@ -64,3 +65,52 @@ void ZigbeeClusterMetering::setAttribute(const ZigbeeClusterAttribute &attribute
qCWarning(dcZigbeeCluster()) << "Unhandled attribute change:" << attribute;
}
}
void ZigbeeClusterMetering::processDataIndication(ZigbeeClusterLibrary::Frame frame)
{
switch (m_direction) {
case Client:
qCWarning(dcZigbeeCluster()) << "Metering: Unhandled ZCL indication in" << m_node << m_endpoint << this << frame;
break;
case Server: {
ServerCommand command = static_cast<ServerCommand>(frame.header.command);
switch (command) {
case CommandDisplayMessage: {
QDataStream stream(frame.payload);
stream.setByteOrder(QDataStream::LittleEndian);
quint32 messageId, time;
quint16 durationInMinutes;
quint8 messageControl;
stream >> messageId >> messageControl >> time >> durationInMinutes;
char messageData[2048]; // At max 2KB, realistically we'll only ever see < 80B in here as larger messages require both ends to negotiate on a larger PDU, however, if the backend supports it, it *may* happen.
int messageLength = stream.readRawData(messageData, 2048);
QByteArray message(messageData, messageLength);
MessageTransmission messageTransmission = static_cast<MessageTransmission>((messageControl & 0xC0) >> 6);
MessagePriority priority = static_cast<MessagePriority>((messageControl & 0x30) >> 4);
bool confirmationRequired = (messageControl & 0x01) == 1;
qCWarning(dcZigbeeCluster()) << "Display message received!" << messageId << messageControl << time << durationInMinutes << message;
emit showMessage(messageId, message, time, durationInMinutes, messageTransmission, priority, confirmationRequired);
break;
}
case ClientCommandCancelMessage: {
QDataStream stream(frame.payload);
stream.setByteOrder(QDataStream::LittleEndian);
quint32 messageId;
quint8 messageControl;
stream >> messageId >> messageControl;
MessageTransmission messageTransmission = static_cast<MessageTransmission>((messageControl & 0xC0) >> 6);
MessagePriority priority = static_cast<MessagePriority>((messageControl & 0x30) >> 4);
bool confirmationRequired = (messageControl & 0x01) == 1;
qCDebug(dcZigbeeCluster()) << "Metering: Cancel message command received" << messageId << messageControl;
emit cancelMessage(messageId, messageTransmission, priority, confirmationRequired);
break;
}
default:
qCDebug(dcZigbeeCluster()) << "Ignoring out of spec metering cluster ZCL indication:" << m_node << m_endpoint << this << frame;
}
break;
}
}
}

View File

@ -555,6 +555,36 @@ public:
};
Q_ENUM(AlarmCode)
enum ClientCommand {
CommandGetProfile = 0x00,
CommandRequestMirrorResponse = 0x01,
CommandMirrorRemoved = 0x02,
CommandRequestFastPollMode = 0x03
};
Q_ENUM(ClientCommand)
enum ServerCommand {
CommandDisplayMessage = 0x00,
ClientCommandCancelMessage = 0x01
};
Q_ENUM(ServerCommand)
enum MessageTransmission {
MessageTransmissionNormal = 0x0,
MessageTransmissionNormalAndAnonymousInterPan = 0x1,
MessageTransmissionAnonymousInterPan = 0x2
};
Q_ENUM(MessageTransmission)
enum MessagePriority {
MessagePriorityLow = 0x0,
MessagePriorityMedium = 0x1,
MessagePriorityHigh = 0x2,
MessagePriorityCritical = 0x3
};
Q_ENUM(MessagePriority)
explicit ZigbeeClusterMetering(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
// Used to refresh formatting attributes (multiplier/divisor)
@ -570,8 +600,12 @@ signals:
void currentSummationDeliveredChanged(quint64 currentSummationDelivered);
void instantaneousDemandChanged(qint32 instantaneousDemand);
void showMessage(quint32 messageId, const QString &message, quint32 time, quint16 durationInMinutes, MessageTransmission transmission, MessagePriority priority, bool confirmationRequired);
void cancelMessage(quint32 messageId, MessageTransmission transmission, MessagePriority priority, bool confirmationRequired);
private:
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
void processDataIndication(ZigbeeClusterLibrary::Frame frame) override;
quint32 m_multiplier = 1;
quint32 m_divisor = 1;