More work on OnOff, LevelControl and ScenesCluster
This alignes the OnOff cluster with the LevelControl cluster in terms of signal behavior: Previously, the OnOff cluster would fire a generic commandSent() signal for some commands and specific signals for others. Effectively forcing the user to connect multiple signals even if only the command would be of interest. The LevelControl cluster instead always fired a generic commandSent() signal and *additionally* more specific signals for parsed parameters. This changes the OnOff cluster to be in line with the LevelCluster as and making the API a bit simpler to use when parameters are not of interest. Also it completes the specific parsing for all 3 clusters.
This commit is contained in:
parent
c5d9b119af
commit
6afc214202
@ -29,6 +29,7 @@
|
|||||||
#include "zigbeenetworkreply.h"
|
#include "zigbeenetworkreply.h"
|
||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
#include "zigbeenetwork.h"
|
#include "zigbeenetwork.h"
|
||||||
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
@ -56,12 +57,12 @@ ZigbeeClusterReply *ZigbeeClusterLevelControl::commandMove(ZigbeeClusterLevelCon
|
|||||||
return executeClusterCommand(ZigbeeClusterLevelControl::CommandMove, payload);
|
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;
|
QByteArray payload;
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(fadeMode) << stepSize << transitionTime;
|
stream << static_cast<quint8>(stepMode) << stepSize << transitionTime;
|
||||||
return executeClusterCommand(ZigbeeClusterLevelControl::CommandStep, payload);
|
return executeClusterCommand(ZigbeeClusterLevelControl::CommandStep, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,12 +89,12 @@ ZigbeeClusterReply *ZigbeeClusterLevelControl::commandMoveWithOnOff(ZigbeeCluste
|
|||||||
return executeClusterCommand(ZigbeeClusterLevelControl::CommandMoveWithOnOff, payload);
|
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;
|
QByteArray payload;
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(fadeMode) << stepSize << transitionTime;
|
stream << static_cast<quint8>(stepMode) << stepSize << transitionTime;
|
||||||
return executeClusterCommand(ZigbeeClusterLevelControl::CommandStepWithOnOff, payload);
|
return executeClusterCommand(ZigbeeClusterLevelControl::CommandStepWithOnOff, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +129,6 @@ void ZigbeeClusterLevelControl::setAttribute(const ZigbeeClusterAttribute &attri
|
|||||||
|
|
||||||
void ZigbeeClusterLevelControl::processDataIndication(ZigbeeClusterLibrary::Frame frame)
|
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
|
// Increase the tsn for continuous id increasing on both sides
|
||||||
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
||||||
|
|
||||||
@ -139,30 +138,48 @@ void ZigbeeClusterLevelControl::processDataIndication(ZigbeeClusterLibrary::Fram
|
|||||||
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
||||||
// Read the payload which is
|
// Read the payload which is
|
||||||
Command command = static_cast<Command>(frame.header.command);
|
Command command = static_cast<Command>(frame.header.command);
|
||||||
qCDebug(dcZigbeeCluster()) << "Command sent from" << m_node << m_endpoint << this << command;
|
|
||||||
emit commandSent(command, frame.payload);
|
emit commandSent(command, frame.payload);
|
||||||
|
|
||||||
|
bool withOnOff = false;
|
||||||
switch (command) {
|
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: {
|
case CommandStep: {
|
||||||
QByteArray payload = frame.payload;
|
QByteArray payload = frame.payload;
|
||||||
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
||||||
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 fadeModeValue = 0; quint8 stepSize; quint16 transitionTime;
|
quint8 stepModeValue = 0; quint8 stepSize; quint16 transitionTime;
|
||||||
payloadStream >> fadeModeValue >> stepSize >> transitionTime;
|
payloadStream >> stepModeValue >> stepSize >> transitionTime;
|
||||||
emit commandStepSent(static_cast<FadeMode>(fadeModeValue), 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<StepMode>(stepModeValue), stepSize, transitionTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CommandMoveWithOnOff:
|
||||||
case CommandMove: {
|
case CommandMove: {
|
||||||
QByteArray payload = frame.payload;
|
QByteArray payload = frame.payload;
|
||||||
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
||||||
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 moveModeValue = 0; quint8 rate;;
|
quint8 moveModeValue = 0; quint8 rate;;
|
||||||
payloadStream >> moveModeValue >> rate;
|
payloadStream >> moveModeValue >> rate;
|
||||||
emit commandMoveSent(static_cast<MoveMode>(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<MoveMode>(moveModeValue), rate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -75,23 +75,23 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(MoveMode)
|
Q_ENUM(MoveMode)
|
||||||
|
|
||||||
enum FadeMode {
|
enum StepMode {
|
||||||
FadeModeUp = 0x00,
|
StepModeUp = 0x00,
|
||||||
FadeModeDown = 0x01
|
StepModeDown = 0x01
|
||||||
};
|
};
|
||||||
Q_ENUM(FadeMode)
|
Q_ENUM(StepMode)
|
||||||
|
|
||||||
explicit ZigbeeClusterLevelControl(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
explicit ZigbeeClusterLevelControl(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||||
|
|
||||||
ZigbeeClusterReply *commandMoveToLevel(quint8 level, quint16 transitionTime = 0xffff);
|
ZigbeeClusterReply *commandMoveToLevel(quint8 level, quint16 transitionTime = 0xffff);
|
||||||
ZigbeeClusterReply *commandMove(MoveMode moveMode, quint8 rate = 0xff);
|
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();
|
ZigbeeClusterReply *commandStop();
|
||||||
|
|
||||||
// With on/off
|
// With on/off
|
||||||
ZigbeeClusterReply *commandMoveToLevelWithOnOff(quint8 level, quint16 transitionTime = 0xffff);
|
ZigbeeClusterReply *commandMoveToLevelWithOnOff(quint8 level, quint16 transitionTime = 0xffff);
|
||||||
ZigbeeClusterReply *commandMoveWithOnOff(MoveMode moveMode, quint8 rate = 0xff);
|
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();
|
ZigbeeClusterReply *commandStopWithOnOff();
|
||||||
|
|
||||||
quint8 currentLevel() const;
|
quint8 currentLevel() const;
|
||||||
@ -107,8 +107,10 @@ protected:
|
|||||||
signals:
|
signals:
|
||||||
void currentLevelChanged(quint8 level);
|
void currentLevelChanged(quint8 level);
|
||||||
void commandSent(ZigbeeClusterLevelControl::Command command, const QByteArray ¶meter = QByteArray());
|
void commandSent(ZigbeeClusterLevelControl::Command command, const QByteArray ¶meter = QByteArray());
|
||||||
void commandMoveSent(MoveMode moveMode, quint8 rate = 0xff);
|
void commandMoveToLevelSent(bool withOnOff, quint8 level, quint16 transitionTime);
|
||||||
void commandStepSent(FadeMode fadeMode, quint8 stepSize, quint16 transitionTime);
|
void commandMoveSent(bool withOnOff, MoveMode moveMode, quint8 rate = 0xff);
|
||||||
|
void commandStepSent(bool withOnOff, StepMode stepMode, quint8 stepSize, quint16 transitionTime);
|
||||||
|
void commandStopSent();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -114,23 +114,15 @@ void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame
|
|||||||
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
if (frame.header.frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
||||||
// Read the payload which is
|
// Read the payload which is
|
||||||
Command command = static_cast<Command>(frame.header.command);
|
Command command = static_cast<Command>(frame.header.command);
|
||||||
qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this;
|
emit commandSent(command, frame.payload);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case CommandOn:
|
|
||||||
emit commandSent(CommandOn);
|
|
||||||
break;
|
|
||||||
case CommandOff:
|
|
||||||
emit commandSent(CommandOff);
|
|
||||||
break;
|
|
||||||
case CommandToggle:
|
|
||||||
emit commandSent(CommandToggle);
|
|
||||||
break;
|
|
||||||
case CommandOffWithEffect: {
|
case CommandOffWithEffect: {
|
||||||
QByteArray payload = frame.payload;
|
QByteArray payload = frame.payload;
|
||||||
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
||||||
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 effectValue = 0; quint16 effectVariant;
|
quint8 effectValue = 0; quint16 effectVariant;
|
||||||
payloadStream >> effectValue >> effectVariant;
|
payloadStream >> effectValue >> effectVariant;
|
||||||
|
qCDebug(dcZigbeeCluster()) << "Command received from" << m_node << m_endpoint << this << command << "effect:" << effectValue << "effectVariant:" << effectVariant;
|
||||||
emit commandOffWithEffectSent(static_cast<Effect>(effectValue), effectVariant);
|
emit commandOffWithEffectSent(static_cast<Effect>(effectValue), effectVariant);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -140,11 +132,12 @@ void ZigbeeClusterOnOff::processDataIndication(ZigbeeClusterLibrary::Frame frame
|
|||||||
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 acceptOnlyWhenOnInt = 0; quint16 onTime; quint16 offTime;
|
quint8 acceptOnlyWhenOnInt = 0; quint16 onTime; quint16 offTime;
|
||||||
payloadStream >> acceptOnlyWhenOnInt >> onTime >> 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<bool>(acceptOnlyWhenOnInt), onTime, offTime);
|
emit commandOnWithTimedOffSent(static_cast<bool>(acceptOnlyWhenOnInt), onTime, offTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ signals:
|
|||||||
void powerChanged(bool power);
|
void powerChanged(bool power);
|
||||||
|
|
||||||
// Client cluster signals
|
// Client cluster signals
|
||||||
void commandSent(Command command);
|
void commandSent(Command command, const QByteArray ¶meters = QByteArray());
|
||||||
// On and off time is in 1/10 seconds
|
// On and off time is in 1/10 seconds
|
||||||
void commandOnWithTimedOffSent(bool acceptOnlyWhenOn, quint16 onTime, quint16 offTime);
|
void commandOnWithTimedOffSent(bool acceptOnlyWhenOn, quint16 onTime, quint16 offTime);
|
||||||
|
|
||||||
|
|||||||
@ -45,8 +45,6 @@ void ZigbeeClusterScenes::setAttribute(const ZigbeeClusterAttribute &attribute)
|
|||||||
|
|
||||||
void ZigbeeClusterScenes::processDataIndication(ZigbeeClusterLibrary::Frame frame)
|
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
|
// Increase the tsn for continuous id increasing on both sides
|
||||||
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
m_transactionSequenceNumber = frame.header.transactionSequenceNumber;
|
||||||
|
|
||||||
@ -54,8 +52,13 @@ void ZigbeeClusterScenes::processDataIndication(ZigbeeClusterLibrary::Frame fram
|
|||||||
case Client: {
|
case Client: {
|
||||||
// Read the payload which is
|
// Read the payload which is
|
||||||
Command command = static_cast<Command>(frame.header.command);
|
Command command = static_cast<Command>(frame.header.command);
|
||||||
qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this << ZigbeeUtils::convertByteArrayToHexString(frame.payload);
|
QByteArray payload = frame.payload;
|
||||||
emit commandSent(frame.header.command, 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;
|
break;
|
||||||
}
|
}
|
||||||
case Server:
|
case Server:
|
||||||
|
|||||||
@ -63,7 +63,7 @@ public:
|
|||||||
explicit ZigbeeClusterScenes(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
explicit ZigbeeClusterScenes(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void commandSent(quint8 command, const QByteArray &payload);
|
void commandSent(Command command, quint16 groupId, quint8 sceneId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user