diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.cpp b/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.cpp index fee03c5..e74a89a 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.cpp +++ b/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.cpp @@ -29,6 +29,7 @@ #include "zigbeenetworkreply.h" #include "loggingcategory.h" #include "zigbeenetwork.h" +#include "zigbeeutils.h" #include @@ -56,12 +57,12 @@ ZigbeeClusterReply *ZigbeeClusterLevelControl::commandMove(ZigbeeClusterLevelCon return executeClusterCommand(ZigbeeClusterLevelControl::CommandMove, payload); } -ZigbeeClusterReply *ZigbeeClusterLevelControl::commandStep(ZigbeeClusterLevelControl::FadeMode fadeMode, quint8 stepSize, quint16 transitionTime) +ZigbeeClusterReply *ZigbeeClusterLevelControl::commandStep(StepMode stepMode, quint8 stepSize, quint16 transitionTime) { QByteArray payload; QDataStream stream(&payload, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::LittleEndian); - stream << static_cast(fadeMode) << stepSize << transitionTime; + stream << static_cast(stepMode) << stepSize << transitionTime; return executeClusterCommand(ZigbeeClusterLevelControl::CommandStep, payload); } @@ -88,12 +89,12 @@ ZigbeeClusterReply *ZigbeeClusterLevelControl::commandMoveWithOnOff(ZigbeeCluste return executeClusterCommand(ZigbeeClusterLevelControl::CommandMoveWithOnOff, payload); } -ZigbeeClusterReply *ZigbeeClusterLevelControl::commandStepWithOnOff(ZigbeeClusterLevelControl::FadeMode fadeMode, quint8 stepSize, quint16 transitionTime) +ZigbeeClusterReply *ZigbeeClusterLevelControl::commandStepWithOnOff(StepMode stepMode, quint8 stepSize, quint16 transitionTime) { QByteArray payload; QDataStream stream(&payload, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::LittleEndian); - stream << static_cast(fadeMode) << stepSize << transitionTime; + stream << static_cast(stepMode) << stepSize << transitionTime; return executeClusterCommand(ZigbeeClusterLevelControl::CommandStepWithOnOff, payload); } @@ -128,8 +129,6 @@ void ZigbeeClusterLevelControl::setAttribute(const ZigbeeClusterAttribute &attri void ZigbeeClusterLevelControl::processDataIndication(ZigbeeClusterLibrary::Frame frame) { - qCDebug(dcZigbeeCluster()) << "Processing cluster frame" << m_node << m_endpoint << this << frame; - // Increase the tsn for continuous id increasing on both sides m_transactionSequenceNumber = frame.header.transactionSequenceNumber; @@ -139,30 +138,48 @@ void ZigbeeClusterLevelControl::processDataIndication(ZigbeeClusterLibrary::Fram if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) { // Read the payload which is Command command = static_cast(frame.header.command); - qCDebug(dcZigbeeCluster()) << "Command sent from" << m_node << m_endpoint << this << command; emit commandSent(command, frame.payload); + bool withOnOff = false; switch (command) { + case CommandMoveToLevelWithOnOff: + case CommandMoveToLevel: { + QByteArray payload = frame.payload; + QDataStream payloadStream(&payload, QIODevice::ReadOnly); + payloadStream.setByteOrder(QDataStream::LittleEndian); + quint8 level; quint16 transitionTime; + payloadStream >> level >> transitionTime; + withOnOff = command == CommandMoveToLevelWithOnOff; + qCDebug(dcZigbeeCluster()).noquote().nospace() << "Command received from " << m_node << " " << m_endpoint << " " << this << " " << command << " withOnOff: " << withOnOff << " level: 0x" << QString::number(level, 16) << " transitionTime: 0x" << QString::number(transitionTime, 16); + emit commandMoveToLevelSent(withOnOff, level, transitionTime); + break; + } + case CommandStepWithOnOff: case CommandStep: { QByteArray payload = frame.payload; QDataStream payloadStream(&payload, QIODevice::ReadOnly); payloadStream.setByteOrder(QDataStream::LittleEndian); - quint8 fadeModeValue = 0; quint8 stepSize; quint16 transitionTime; - payloadStream >> fadeModeValue >> stepSize >> transitionTime; - emit commandStepSent(static_cast(fadeModeValue), stepSize, transitionTime); + quint8 stepModeValue = 0; quint8 stepSize; quint16 transitionTime; + payloadStream >> stepModeValue >> stepSize >> transitionTime; + withOnOff = command == CommandMoveToLevelWithOnOff; + qCDebug(dcZigbeeCluster()).noquote().nospace() << "Command received from " << m_node << " " << m_endpoint << " " << this << " " << command << " withOnOff: " << withOnOff << " stepModeValue: 0x" << QString::number(stepModeValue, 16) << " stepSize: 0x" << QString::number(stepSize, 16) << " transitionTime: 0x" << QString::number(transitionTime, 16); + emit commandStepSent(withOnOff, static_cast(stepModeValue), stepSize, transitionTime); break; } + case CommandMoveWithOnOff: case CommandMove: { QByteArray payload = frame.payload; QDataStream payloadStream(&payload, QIODevice::ReadOnly); payloadStream.setByteOrder(QDataStream::LittleEndian); quint8 moveModeValue = 0; quint8 rate;; payloadStream >> moveModeValue >> rate; - emit commandMoveSent(static_cast(moveModeValue), rate); + withOnOff = command == CommandMoveToLevelWithOnOff; + qCDebug(dcZigbeeCluster()).noquote().nospace() << "Command received from " << m_node << " " << m_endpoint << " " << this << " " << command << " withOnOff:" << withOnOff << " moveModeValue: 0x" << QString::number(moveModeValue, 16) << " rate: 0x" << QString::number(rate, 16); + emit commandMoveSent(withOnOff, static_cast(moveModeValue), rate); break; } default: - qCDebug(dcZigbeeCluster()) << "Command received without special implementation"; + qCDebug(dcZigbeeCluster()).noquote().nospace() << "Command received from " << m_node << " " << m_endpoint << " " << this << " " << command << " payload: 0x" << ZigbeeUtils::convertByteArrayToHexString(frame.payload); break; } diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.h b/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.h index 0f6f346..82001e6 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusterlevelcontrol.h @@ -75,23 +75,23 @@ public: }; Q_ENUM(MoveMode) - enum FadeMode { - FadeModeUp = 0x00, - FadeModeDown = 0x01 + enum StepMode { + StepModeUp = 0x00, + StepModeDown = 0x01 }; - Q_ENUM(FadeMode) + Q_ENUM(StepMode) explicit ZigbeeClusterLevelControl(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); ZigbeeClusterReply *commandMoveToLevel(quint8 level, quint16 transitionTime = 0xffff); ZigbeeClusterReply *commandMove(MoveMode moveMode, quint8 rate = 0xff); - ZigbeeClusterReply *commandStep(FadeMode fadeMode, quint8 stepSize = 0x01, quint16 transitionTime = 0xffff); + ZigbeeClusterReply *commandStep(StepMode stepMode, quint8 stepSize = 0x01, quint16 transitionTime = 0xffff); ZigbeeClusterReply *commandStop(); // With on/off ZigbeeClusterReply *commandMoveToLevelWithOnOff(quint8 level, quint16 transitionTime = 0xffff); ZigbeeClusterReply *commandMoveWithOnOff(MoveMode moveMode, quint8 rate = 0xff); - ZigbeeClusterReply *commandStepWithOnOff(FadeMode fadeMode, quint8 stepSize = 0x01, quint16 transitionTime = 0xffff); + ZigbeeClusterReply *commandStepWithOnOff(StepMode stepMode, quint8 stepSize = 0x01, quint16 transitionTime = 0xffff); ZigbeeClusterReply *commandStopWithOnOff(); quint8 currentLevel() const; @@ -107,8 +107,10 @@ protected: signals: void currentLevelChanged(quint8 level); void commandSent(ZigbeeClusterLevelControl::Command command, const QByteArray ¶meter = QByteArray()); - void commandMoveSent(MoveMode moveMode, quint8 rate = 0xff); - void commandStepSent(FadeMode fadeMode, quint8 stepSize, quint16 transitionTime); + void commandMoveToLevelSent(bool withOnOff, quint8 level, quint16 transitionTime); + void commandMoveSent(bool withOnOff, MoveMode moveMode, quint8 rate = 0xff); + void commandStepSent(bool withOnOff, StepMode stepMode, quint8 stepSize, quint16 transitionTime); + void commandStopSent(); }; diff --git a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp index c13bddd..aae0ff6 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp +++ b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.cpp @@ -114,23 +114,15 @@ void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) { // Read the payload which is Command command = static_cast(frame.header.command); - qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this; + emit commandSent(command, frame.payload); switch (command) { - case CommandOn: - emit commandSent(CommandOn); - break; - case CommandOff: - emit commandSent(CommandOff); - break; - case CommandToggle: - emit commandSent(CommandToggle); - break; case CommandOffWithEffect: { QByteArray payload = frame.payload; QDataStream payloadStream(&payload, QIODevice::ReadOnly); payloadStream.setByteOrder(QDataStream::LittleEndian); quint8 effectValue = 0; quint16 effectVariant; payloadStream >> effectValue >> effectVariant; + qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command << "effect:" << effectValue << "effectVariant:" << effectVariant; emit commandOffWithEffectSent(static_cast(effectValue), effectVariant); break; } @@ -140,11 +132,12 @@ void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame payloadStream.setByteOrder(QDataStream::LittleEndian); quint8 acceptOnlyWhenOnInt = 0; quint16 onTime; quint16 offTime; payloadStream >> acceptOnlyWhenOnInt >> onTime >> offTime; + qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command << "accentOnlyWhenOnInt:" << acceptOnlyWhenOnInt << "onTime:" << onTime << "offTime:" << offTime; emit commandOnWithTimedOffSent(static_cast(acceptOnlyWhenOnInt), onTime, offTime); break; } default: - qCWarning(dcZigbeeCluster()) << "Unhandled command sent from" << m_node << m_endpoint << this << command << ZigbeeUtils::convertByteArrayToHexString(frame.payload); + qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command << ZigbeeUtils::convertByteArrayToHexString(frame.payload); break; } } diff --git a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h index 561ff8f..1434d27 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusteronoff.h @@ -94,7 +94,7 @@ signals: void powerChanged(bool power); // Client cluster signals - void commandSent(Command command); + void commandSent(Command command, const QByteArray ¶meters = QByteArray()); // On and off time is in 1/10 seconds void commandOnWithTimedOffSent(bool acceptOnlyWhenOn, quint16 onTime, quint16 offTime); diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterscenes.cpp b/libnymea-zigbee/zcl/general/zigbeeclusterscenes.cpp index 3d04521..ff0b48a 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterscenes.cpp +++ b/libnymea-zigbee/zcl/general/zigbeeclusterscenes.cpp @@ -45,8 +45,6 @@ void ZigbeeClusterScenes::setAttribute(const ZigbeeClusterAttribute &attribute) void ZigbeeClusterScenes::processDataIndication(ZigbeeClusterLibrary::Frame frame) { - qCDebug(dcZigbeeCluster()) << "Processing cluster frame" << m_node << m_endpoint << this << frame; - // Increase the tsn for continuous id increasing on both sides m_transactionSequenceNumber = frame.header.transactionSequenceNumber; @@ -54,8 +52,13 @@ void ZigbeeClusterScenes::processDataIndication(ZigbeeClusterLibrary::Frame fram case Client: { // Read the payload which is Command command = static_cast(frame.header.command); - qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this << ZigbeeUtils::convertByteArrayToHexString(frame.payload); - emit commandSent(frame.header.command, frame.payload); + QByteArray payload = frame.payload; + QDataStream payloadStream(&payload, QIODevice::ReadOnly); + payloadStream.setByteOrder(QDataStream::LittleEndian); + quint16 groupId = 0; quint8 sceneId; + payloadStream >> groupId >> sceneId; + qCDebug(dcZigbeeCluster()).noquote() << "Received" << command << "for group" << "0x" + QString::number(groupId, 16) << "and scene" << sceneId << "from" << m_node << m_endpoint << this; + emit commandSent(command, groupId, sceneId); break; } case Server: diff --git a/libnymea-zigbee/zcl/general/zigbeeclusterscenes.h b/libnymea-zigbee/zcl/general/zigbeeclusterscenes.h index c169247..7333f60 100644 --- a/libnymea-zigbee/zcl/general/zigbeeclusterscenes.h +++ b/libnymea-zigbee/zcl/general/zigbeeclusterscenes.h @@ -63,7 +63,7 @@ public: explicit ZigbeeClusterScenes(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); signals: - void commandSent(quint8 command, const QByteArray &payload); + void commandSent(Command command, quint16 groupId, quint8 sceneId); private: void setAttribute(const ZigbeeClusterAttribute &attribute) override;