Add scene cluster basic structure
parent
2893f39e61
commit
94539c0d02
|
|
@ -57,6 +57,7 @@ public:
|
|||
NotificationNetworkStarted = 0x7E,
|
||||
NotificationApsDataConfirm = 0x80,
|
||||
NotificationApsDataIndication = 0x81,
|
||||
NotificationApsDataAck = 0x82,
|
||||
NotificationNodeJoined = 0x90,
|
||||
NotificationNodeLeft = 0x91,
|
||||
NotificationDebugMessage = 0xFE
|
||||
|
|
|
|||
|
|
@ -511,11 +511,25 @@ void ZigbeeBridgeControllerNxp::onInterfacePackageReceived(const QByteArray &pac
|
|||
stream >> confirm.sourceEndpoint >> confirm.destinationEndpoint >> confirm.zigbeeStatusCode;
|
||||
|
||||
qCDebug(dcZigbeeController()) << confirm;
|
||||
qCDebug(dcZigbeeAps()) << "APSDE-DATA.confirm" << confirm;
|
||||
qCDebug(dcZigbeeAps()) << confirm;
|
||||
|
||||
emit apsDataConfirmReceived(confirm);
|
||||
break;
|
||||
}
|
||||
case Nxp::NotificationApsDataAck: {
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
Zigbee::ApsdeDataAck acknowledgement;
|
||||
stream >> acknowledgement.requestId >> acknowledgement.zigbeeStatusCode >> acknowledgement.sourceEndpoint;
|
||||
stream >> acknowledgement.destinationAddressMode >> acknowledgement.destinationAddress >> acknowledgement.destinationEndpoint;
|
||||
stream >> acknowledgement.profileId >> acknowledgement.clusterId;
|
||||
|
||||
qCDebug(dcZigbeeController()) << acknowledgement;
|
||||
qCDebug(dcZigbeeAps()) << acknowledgement;
|
||||
|
||||
emit apsDataAckReceived(acknowledgement);
|
||||
break;
|
||||
}
|
||||
case Nxp::NotificationApsDataIndication: {
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ void ZigbeeNetworkNxp::onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &
|
|||
{
|
||||
ZigbeeNetworkReply *reply = m_pendingReplies.value(confirm.requestId);
|
||||
if (!reply) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Received confirmation but could not find any reply. Ignoring the confirmation";
|
||||
qCDebug(dcZigbeeNetwork()) << "Received confirmation but could not find any reply. Ignoring the confirmation" << confirm;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -554,6 +554,15 @@ void ZigbeeNetworkNxp::onApsDataIndicationReceived(const Zigbee::ApsdeDataIndica
|
|||
handleZigbeeClusterLibraryIndication(indication);
|
||||
}
|
||||
|
||||
void ZigbeeNetworkNxp::onApsDataAckReceived(const Zigbee::ApsdeDataAck &acknowledgement)
|
||||
{
|
||||
ZigbeeNetworkReply *reply = m_pendingReplies.value(acknowledgement.requestId);
|
||||
if (reply && reply->buffered()) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Buffered frame from network request has been acknowledged" << acknowledgement;
|
||||
setReplyResponseError(reply, static_cast<Zigbee::ZigbeeApsStatus>(acknowledgement.zigbeeStatusCode));
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeNetworkNxp::onNodeLeftIndication(const ZigbeeAddress &ieeeAddress, bool rejoining)
|
||||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Received node left indication" << ieeeAddress.toString() << "rejoining:" << rejoining;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ private slots:
|
|||
|
||||
void onApsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
|
||||
void onApsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);
|
||||
void onApsDataAckReceived(const Zigbee::ApsdeDataAck &acknowledgement);
|
||||
|
||||
void onNodeLeftIndication(const ZigbeeAddress &ieeeAddress, bool rejoining);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ SOURCES += \
|
|||
zcl/general/zigbeeclustermultistatevalue.cpp \
|
||||
zcl/general/zigbeeclusteronoff.cpp \
|
||||
zcl/general/zigbeeclusterpowerconfiguration.cpp \
|
||||
zcl/general/zigbeeclusterscenes.cpp \
|
||||
zcl/hvac/zigbeeclusterthermostat.cpp \
|
||||
zcl/lighting/zigbeeclustercolorcontrol.cpp \
|
||||
zcl/measurement/zigbeeclusterilluminancemeasurment.cpp \
|
||||
|
|
@ -103,6 +104,7 @@ HEADERS += \
|
|||
zcl/general/zigbeeclustermultistatevalue.h \
|
||||
zcl/general/zigbeeclusteronoff.h \
|
||||
zcl/general/zigbeeclusterpowerconfiguration.h \
|
||||
zcl/general/zigbeeclusterscenes.h \
|
||||
zcl/hvac/zigbeeclusterthermostat.h \
|
||||
zcl/lighting/zigbeeclustercolorcontrol.h \
|
||||
zcl/measurement/zigbeeclusterilluminancemeasurment.h \
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public:
|
|||
|
||||
enum MoveMode {
|
||||
MoveModeUp = 0x00,
|
||||
ModeModeDown = 0x01
|
||||
MoveModeDown = 0x01
|
||||
};
|
||||
Q_ENUM(MoveMode)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea-zigbee.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "zigbeeclusterscenes.h"
|
||||
#include "loggingcategory.h"
|
||||
#include "zigbeeutils.h"
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
ZigbeeClusterScenes::ZigbeeClusterScenes(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, ZigbeeCluster::Direction direction, QObject *parent) :
|
||||
ZigbeeCluster(network, node, endpoint, ZigbeeClusterLibrary::ClusterIdScenes, direction, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeClusterScenes::setAttribute(const ZigbeeClusterAttribute &attribute)
|
||||
{
|
||||
qCDebug(dcZigbeeCluster()) << "Update attribute" << m_node << m_endpoint << this << static_cast<Attribute>(attribute.id()) << attribute.dataType();
|
||||
updateOrAddAttribute(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;
|
||||
|
||||
switch (m_direction) {
|
||||
case Client: {
|
||||
// Read the payload which is
|
||||
Command command = static_cast<Command>(frame.header.command);
|
||||
qCDebug(dcZigbeeCluster()) << "Received" << command << "from" << m_node << m_endpoint << this << ZigbeeUtils::convertByteArrayToHexString(frame.payload);
|
||||
emit commandSent(frame.header.command, frame.payload);
|
||||
break;
|
||||
}
|
||||
case Server:
|
||||
qCWarning(dcZigbeeCluster()) << "Unhandled ZCL indication in" << m_node << m_endpoint << this << frame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea-zigbee.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef ZIGBEECLUSTERSCENES_H
|
||||
#define ZIGBEECLUSTERSCENES_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "zcl/zigbeecluster.h"
|
||||
|
||||
class ZigbeeClusterScenes : public ZigbeeCluster
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Attribute {
|
||||
AttributeSceneCount = 0x0000,
|
||||
AttributeCurrentScene = 0x0001,
|
||||
AttributeCurrentGroup = 0x0002,
|
||||
AttributeSceneValid = 0x0003,
|
||||
AttributeNameSupported = 0x0004,
|
||||
AttributeLastConfiguredBy = 0x0005 // Optional
|
||||
};
|
||||
Q_ENUM(Attribute)
|
||||
|
||||
enum Command {
|
||||
CommandAddScene = 0x00,
|
||||
CommandViewScene = 0x01,
|
||||
CommandRemoveScene = 0x02,
|
||||
CommandRemoveAllScenes = 0x03,
|
||||
CommandStoreScene = 0x04,
|
||||
CommandRecallScene = 0x05,
|
||||
CommandGetSceneMembership = 0x06,
|
||||
CommandEnhancedAddScene= 0x40, // O
|
||||
CommandEnhancedViewScene= 0x41, // O
|
||||
CommandCopyScene= 0x42 // O
|
||||
};
|
||||
Q_ENUM(Command)
|
||||
|
||||
explicit ZigbeeClusterScenes(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void commandSent(quint8 command, const QByteArray &payload);
|
||||
|
||||
private:
|
||||
void setAttribute(const ZigbeeClusterAttribute &attribute) override;
|
||||
|
||||
protected:
|
||||
void processDataIndication(ZigbeeClusterLibrary::Frame frame) override;
|
||||
|
||||
};
|
||||
|
||||
#endif // ZIGBEECLUSTERSCENES_H
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataConfirm &confirm)
|
||||
{
|
||||
debug.nospace() << "APSDE-DATA.confirm(";
|
||||
debug.nospace() << "Request ID: " << confirm.requestId << ", ";
|
||||
debug.nospace() << "SQN: " << confirm.requestId << ", ";
|
||||
|
||||
if (confirm.destinationAddressMode == Zigbee::DestinationAddressModeGroup)
|
||||
debug.nospace() << "Group address:" << ZigbeeUtils::convertUint16ToHexString(confirm.destinationShortAddress) << ", ";
|
||||
|
|
@ -84,3 +84,25 @@ QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataIndication &indication)
|
|||
debug.nospace() << "RSSI: " << indication.rssi << "dBm)";
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataAck &acknowledgement)
|
||||
{
|
||||
debug.nospace() << "APSDE-DATA.acknowledgement(";
|
||||
debug.nospace() << "SQN: " << acknowledgement.requestId << ", ";
|
||||
if (acknowledgement.destinationAddressMode == Zigbee::DestinationAddressModeGroup) {
|
||||
debug.nospace() << "Group address:" << ZigbeeUtils::convertUint16ToHexString(acknowledgement.destinationAddress) << ", ";
|
||||
} else {
|
||||
debug.nospace() << "Network address:" << ZigbeeUtils::convertUint16ToHexString(acknowledgement.destinationAddress) << ", ";
|
||||
}
|
||||
debug.nospace() << "Destination EP:" << ZigbeeUtils::convertByteToHexString(acknowledgement.destinationEndpoint) << ", ";
|
||||
debug.nospace() << "Source EP:" << ZigbeeUtils::convertByteToHexString(acknowledgement.sourceEndpoint) << ", ";
|
||||
debug.nospace() << static_cast<Zigbee::ZigbeeProfile>(acknowledgement.profileId) << ", ";
|
||||
if (acknowledgement.profileId == static_cast<quint16>(Zigbee::ZigbeeProfileDevice)) {
|
||||
debug.nospace() << static_cast<ZigbeeDeviceProfile::ZdoCommand>(acknowledgement.clusterId) << ", ";
|
||||
} else {
|
||||
debug.nospace() << static_cast<ZigbeeClusterLibrary::ClusterId>(acknowledgement.clusterId) << ", ";
|
||||
}
|
||||
debug.nospace() << static_cast<ZigbeeClusterLibrary::Status>(acknowledgement.zigbeeStatusCode);
|
||||
debug.nospace() << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,11 +320,12 @@ public:
|
|||
ZigbeeNwkLayerStatusMaxFrmCntr = 0xcc,
|
||||
ZigbeeNwkLayerStatusNoKey = 0xcd,
|
||||
ZigbeeNwkLayerStatusBadCcmOutput = 0xce,
|
||||
ZigbeeNwkLayerStatusNoRoutingCapacity = 0xef, // Resource problem on the hardware
|
||||
ZigbeeNwkLayerStatusRouteDiscoveryFailed = 0xd0,
|
||||
ZigbeeNwkLayerStatusRouteError = 0xd1,
|
||||
ZigbeeNwkLayerStatusBtTableFull = 0xd2,
|
||||
ZigbeeNwkLayerStatusFrameNotBuffered = 0xd3,
|
||||
ZigbeeNwkLayerStatusFrameBuffered = 0xd4
|
||||
ZigbeeNwkLayerStatusFrameBuffered = 0xd4 // Buffered until route discovery has been done
|
||||
};
|
||||
Q_ENUM(ZigbeeNwkLayerStatus)
|
||||
|
||||
|
|
@ -377,6 +378,16 @@ public:
|
|||
qint8 rssi = 0;
|
||||
} ApsdeDataIndication;
|
||||
|
||||
typedef struct ApsdeDataAck {
|
||||
quint8 requestId = 0;
|
||||
quint8 destinationAddressMode = Zigbee::DestinationAddressModeShortAddress;
|
||||
quint16 destinationAddress = 0;
|
||||
quint8 destinationEndpoint = 0;
|
||||
quint8 sourceEndpoint = 0;
|
||||
quint16 profileId = 0;
|
||||
quint16 clusterId = 0;
|
||||
quint8 zigbeeStatusCode = 0;
|
||||
} ApsdeDataAck;
|
||||
|
||||
///* Manufacturer Codes */
|
||||
///* Codes less than 0x1000 were issued for RF4CE */
|
||||
|
|
@ -1069,11 +1080,11 @@ public:
|
|||
//#define ZBEE_MFG_SWANN "Swann Communications"
|
||||
//#define ZBEE_MFG_TI "Texas Instruments"
|
||||
|
||||
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataConfirm &confirm);
|
||||
QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataIndication &indication);
|
||||
QDebug operator<<(QDebug debug, const Zigbee::ApsdeDataAck &acknowledgement);
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Zigbee::ZigbeeChannels)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Zigbee::ZigbeeTxOptions)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ signals:
|
|||
// APS notifications
|
||||
void apsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
|
||||
void apsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);
|
||||
void apsDataAckReceived(const Zigbee::ApsdeDataAck &acknowledgement);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -843,9 +843,16 @@ void ZigbeeNetwork::setReplyResponseError(ZigbeeNetworkReply *reply, Zigbee::Zig
|
|||
finishNetworkReply(reply);
|
||||
} else {
|
||||
// There has been an error while transporting the request to the device
|
||||
// Note: if the APS status is >= 0xc1, it has to interpreted as NWK layer error
|
||||
if (zigbeeApsStatus >= 0xc1 && zigbeeApsStatus <= 0xd4) {
|
||||
reply->m_zigbeeNwkStatus = static_cast<Zigbee::ZigbeeNwkLayerStatus>(static_cast<quint8>(zigbeeApsStatus));
|
||||
if (reply->zigbeeNwkStatus() == Zigbee::ZigbeeNwkLayerStatusFrameBuffered) {
|
||||
// The frame has been buffered and will be sent once the route has been discovered.
|
||||
// If the ACK will arrive, the frame was sent successfully, otherwise on timeout the request failed
|
||||
reply->m_buffered = true;
|
||||
// Restart the timer and wait for ack
|
||||
reply->m_timer->start();
|
||||
return;
|
||||
}
|
||||
finishNetworkReply(reply, ZigbeeNetworkReply::ErrorZigbeeNwkStatusError);
|
||||
} else if (zigbeeApsStatus >= 0xE0 && zigbeeApsStatus <= 0xF4) {
|
||||
reply->m_zigbeeMacStatus = static_cast<Zigbee::ZigbeeMacLayerStatus>(static_cast<quint8>(zigbeeApsStatus));
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ Zigbee::ZigbeeApsStatus ZigbeeNetworkReply::zigbeeApsStatus() const
|
|||
return m_zigbeeApsStatus;
|
||||
}
|
||||
|
||||
bool ZigbeeNetworkReply::buffered() const
|
||||
{
|
||||
return m_buffered;
|
||||
}
|
||||
|
||||
Zigbee::ZigbeeNwkLayerStatus ZigbeeNetworkReply::zigbeeNwkStatus() const
|
||||
{
|
||||
return m_zigbeeNwkStatus;
|
||||
|
|
@ -60,7 +65,13 @@ ZigbeeNetworkReply::ZigbeeNetworkReply(const ZigbeeNetworkRequest &request, QObj
|
|||
m_timer->setSingleShot(true);
|
||||
m_timer->setInterval(10000);
|
||||
connect(m_timer, &QTimer::timeout, this, [this](){
|
||||
if (m_buffered) {
|
||||
// We did not receive any reply from the buffered message, assuming the route could not be discovered to the device
|
||||
m_zigbeeNwkStatus = Zigbee::ZigbeeNwkLayerStatusRouteDiscoveryFailed;
|
||||
m_error = ErrorZigbeeNwkStatusError;
|
||||
} else {
|
||||
m_error = ErrorTimeout;
|
||||
}
|
||||
emit finished();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,10 +60,13 @@ public:
|
|||
Zigbee::ZigbeeNwkLayerStatus zigbeeNwkStatus() const;
|
||||
Zigbee::ZigbeeApsStatus zigbeeApsStatus() const;
|
||||
|
||||
bool buffered() const;
|
||||
|
||||
private:
|
||||
explicit ZigbeeNetworkReply(const ZigbeeNetworkRequest &request, QObject *parent = nullptr);
|
||||
ZigbeeNetworkRequest m_request;
|
||||
QTimer *m_timer = nullptr;
|
||||
bool m_buffered = false;
|
||||
|
||||
Error m_error = ErrorNoError;
|
||||
Zigbee::ZigbeeMacLayerStatus m_zigbeeMacStatus = Zigbee::ZigbeeMacLayerStatusSuccess;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(ZigbeeClusterLibrary::ClusterId
|
|||
return new ZigbeeClusterLevelControl(m_network, m_node, this, direction, this);
|
||||
case ZigbeeClusterLibrary::ClusterIdGroups:
|
||||
return new ZigbeeClusterGroups(m_network, m_node, this, direction, this);
|
||||
case ZigbeeClusterLibrary::ClusterIdScenes:
|
||||
return new ZigbeeClusterScenes(m_network, m_node, this, direction, this);
|
||||
case ZigbeeClusterLibrary::ClusterIdAnalogInput:
|
||||
return new ZigbeeClusterAnalogInput(m_network, m_node, this, direction, this);
|
||||
case ZigbeeClusterLibrary::ClusterIdAnalogOutput:
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "zcl/general/zigbeeclusterlevelcontrol.h"
|
||||
#include "zcl/general/zigbeeclusterpowerconfiguration.h"
|
||||
#include "zcl/general/zigbeeclustergroups.h"
|
||||
#include "zcl/general/zigbeeclusterscenes.h"
|
||||
#include "zcl/general/zigbeeclusteranaloginput.h"
|
||||
#include "zcl/general/zigbeeclusteranalogoutput.h"
|
||||
#include "zcl/general/zigbeeclusteranalogvalue.h"
|
||||
|
|
|
|||
Loading…
Reference in New Issue