Implement commands for metering cluster
Main reasoning behind this is actually that Tuya devices seem to send a CancelMessage command every other minute and are currently spamming the log with unhandled ZCL indication warnings. Instead of just silencing the warning (which is very useful most of the times) I decided to complete the implementation of the metering cluster and actually make it a handled ZCL indication.
This commit is contained in:
parent
69d1709358
commit
92cdc4bc84
@ -1,5 +1,6 @@
|
|||||||
#include "zigbeeclustermetering.h"
|
#include "zigbeeclustermetering.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeCluster)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeCluster)
|
||||||
|
|
||||||
@ -64,3 +65,52 @@ void ZigbeeClusterMetering::setAttribute(const ZigbeeClusterAttribute &attribute
|
|||||||
qCWarning(dcZigbeeCluster()) << "Unhandled attribute change:" << 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -555,6 +555,36 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(AlarmCode)
|
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);
|
explicit ZigbeeClusterMetering(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||||
|
|
||||||
// Used to refresh formatting attributes (multiplier/divisor)
|
// Used to refresh formatting attributes (multiplier/divisor)
|
||||||
@ -570,8 +600,12 @@ signals:
|
|||||||
void currentSummationDeliveredChanged(quint64 currentSummationDelivered);
|
void currentSummationDeliveredChanged(quint64 currentSummationDelivered);
|
||||||
void instantaneousDemandChanged(qint32 instantaneousDemand);
|
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:
|
private:
|
||||||
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
||||||
|
void processDataIndication(ZigbeeClusterLibrary::Frame frame) override;
|
||||||
|
|
||||||
quint32 m_multiplier = 1;
|
quint32 m_multiplier = 1;
|
||||||
quint32 m_divisor = 1;
|
quint32 m_divisor = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user