Start implementing clusters

This commit is contained in:
Simon Stürz 2020-05-06 12:33:26 +02:00
parent 3e8da8ee26
commit 7cdf772b1a
36 changed files with 627 additions and 215 deletions

View File

@ -18,3 +18,17 @@ Depending on your available hardware following gateway modules are supported
* RaspBee
* ConBee II
* RaspBee II
## Structure
ZigbeeNetwork
- ZDO handler
- ZCL handler
- ZHA handler
- ZLL handler
- GP handler
- [ZigbeeNode]
- [ZigbeeNodeEndpoints]
- Profile

View File

@ -1,4 +1,4 @@
QT += gui serialport
QT += gui serialport sql
QMAKE_CXXFLAGS += -Werror -std=c++11
QMAKE_LFLAGS += -std=c++11

View File

@ -28,7 +28,7 @@
#include "zigbeeutils.h"
#include "loggingcategory.h"
#include "zigbeechannelmask.h"
#include "zigbeedeviceprofile.h"
#include "zdo/zigbeedeviceprofile.h"
#include "zigbeebridgecontrollerdeconz.h"
#include <QDataStream>

View File

@ -25,8 +25,8 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zdo/zigbeedeviceprofile.h"
#include "zigbeenetworkdeconz.h"
#include "zigbeedeviceprofile.h"
#include "loggingcategory.h"
#include "zigbeeutils.h"
@ -109,11 +109,6 @@ ZigbeeNetworkReply *ZigbeeNetworkDeconz::setPermitJoin(quint16 shortAddress, qui
return sendRequest(request);
}
quint8 ZigbeeNetworkDeconz::generateSequenceNumber()
{
return m_sequenceNumber++;
}
void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetworkState state)
{
if (m_createState == state)
@ -322,8 +317,8 @@ void ZigbeeNetworkDeconz::handleZigbeeDeviceProfileIndication(const DeconzApsDat
return;
}
// Check if this is a response for a ZDO request
foreach (ZigbeeNetworkReply *reply, m_pendingReplies.values()) {
// Check if this is a response for a ZDO request
if (reply->request().profileId() == Zigbee::ZigbeeProfileDevice) {
// We have a reply which is waiting for a ZDO response, lets check if they match
// Check if this is the response to the sent request command
@ -347,6 +342,16 @@ void ZigbeeNetworkDeconz::handleZigbeeDeviceProfileIndication(const DeconzApsDat
}
qCWarning(dcZigbeeNetwork()) << "FIXME: Unhandled ZDO indication" << indication;
}
void ZigbeeNetworkDeconz::handleZigbeeHomeAutomationIndication(const DeconzApsDataIndication &indication)
{
ZigbeeClusterLibrary::Frame frame = ZigbeeClusterLibrary::parseFrameData(static_cast<Zigbee::ClusterId>(indication.clusterId), indication.asdu);
qCDebug(dcZigbeeNetwork()) << "ZCL HA" << indication << frame;
}
ZigbeeNode *ZigbeeNetworkDeconz::createNode(QObject *parent)
@ -412,22 +417,8 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
// Check if we have to create a pan ID and select the channel
if (panId() == 0) {
m_createNewNetwork = true;
//setExtendedPanId(ZigbeeUtils::generateRandomPanId());
//qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
}
// Note: we cannot read or write the network key here.
// if (securityConfiguration().networkKey().isNull()) {
// m_createNewNetwork = true;
// qCDebug(dcZigbeeNetwork()) << "Create a new network key";
// ZigbeeNetworkKey key = ZigbeeNetworkKey::generateKey();
// m_securityConfiguration.setNetworkKey(key);
// }
//qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().networkKey() << "network link key";
//qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().globalTrustCenterLinkKey() << "global trust center link key";
// - Read the firmware version
// - Read the network configuration parameters
// - Read the network state
@ -630,6 +621,15 @@ void ZigbeeNetworkDeconz::onAspDataIndicationReceived(const DeconzApsDataIndicat
return;
}
if (indication.profileId == Zigbee::ZigbeeProfileLightLink) {
}
if (indication.profileId == Zigbee::ZigbeeProfileHomeAutomation) {
handleZigbeeHomeAutomationIndication(indication);
return;
}
// FIXME: handle it
qCDebug(dcZigbeeNetwork()) << "Unhandled indication" << indication;
@ -660,7 +660,7 @@ void ZigbeeNetworkDeconz::startNetwork()
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
setState(StateOffline);
//setStartingState(StartingStateNone);
setCreateNetworkState(CreateNetworkStateIdle);
setError(ErrorHardwareUnavailable);
return;
}

View File

@ -33,6 +33,7 @@
#include "zigbeenetwork.h"
#include "zigbeenodedeconz.h"
#include "zigbeechannelmask.h"
#include "zigbeeclusterlibrary.h"
#include "zigbeebridgecontrollerdeconz.h"
class ZigbeeNetworkDeconz : public ZigbeeNetwork
@ -57,8 +58,6 @@ public:
ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress, quint8 duration);
quint8 generateSequenceNumber();
private:
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
bool m_networkRunning = false;
@ -69,8 +68,6 @@ private:
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
quint8 m_sequenceNumber = 0;
QTimer *m_pollNetworkStateTimer = nullptr;
void setCreateNetworkState(CreateNetworkState state);
@ -80,6 +77,7 @@ private:
// ZZL
// HA
void handleZigbeeHomeAutomationIndication(const DeconzApsDataIndication &indication);
// GP

View File

@ -27,7 +27,7 @@
#include "zigbeeutils.h"
#include "zigbeenodedeconz.h"
#include "zigbeedeviceprofile.h"
#include "zdo/zigbeedeviceprofile.h"
#include "zigbeenetworkdeconz.h"
#include "zigbeenodeendpointdeconz.h"
@ -36,7 +36,7 @@
#include <QDataStream>
ZigbeeNodeDeconz::ZigbeeNodeDeconz(ZigbeeNetworkDeconz *network, QObject *parent) :
ZigbeeNode(parent),
ZigbeeNode(network, parent),
m_network(network)
{
@ -138,10 +138,45 @@ ZigbeeNetworkReply *ZigbeeNodeDeconz::requestSimpleDescriptor(quint8 endpoint)
return m_network->sendRequest(request);
}
ZigbeeNetworkReply *ZigbeeNodeDeconz::requestLeaveNetwork(bool rejoin, bool removeChildren)
{
ZigbeeNetworkRequest request;
request.setRequestId(m_network->generateSequenceNumber());
request.setDestinationAddressMode(Zigbee::DestinationAddressModeShortAddress);
request.setDestinationShortAddress(shortAddress());
request.setDestinationEndpoint(0); // ZDO
request.setProfileId(Zigbee::ZigbeeProfileDevice); // ZDP
request.setClusterId(ZigbeeDeviceProfile::MgmtLeaveRequest);
request.setSourceEndpoint(0); // ZDO
// Build ASDU
QByteArray asdu;
quint8 leaveFlag = 0;
if (rejoin) {
leaveFlag |= 0x01;
}
if (removeChildren) {
leaveFlag |= 0x02;
}
QDataStream stream(&asdu, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << request.requestId() << extendedAddress().toUInt64() << leaveFlag;
request.setAsdu(asdu);
// We expect an indication with the response and the confirmation
request.setExpectIndication(true);
return m_network->sendRequest(request);
}
void ZigbeeNodeDeconz::leaveNetworkRequest(bool rejoin, bool removeChildren)
{
Q_UNUSED(rejoin)
Q_UNUSED(removeChildren)
ZigbeeNetworkReply *reply = requestLeaveNetwork(rejoin, removeChildren);
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
// TODO: check reply error
});
}
void ZigbeeNodeDeconz::initNodeDescriptor()
@ -309,7 +344,7 @@ void ZigbeeNodeDeconz::initEndpoints()
// Create endpoint
ZigbeeNodeEndpointDeconz *endpoint = nullptr;
if (!hasEndpoint(endpointId)) {
ZigbeeNodeEndpointDeconz *endpoint = qobject_cast<ZigbeeNodeEndpointDeconz *>(createNodeEndpoint(endpointId, this));
endpoint = qobject_cast<ZigbeeNodeEndpointDeconz *>(createNodeEndpoint(endpointId, this));
m_endpoints.append(endpoint);
} else {
endpoint = qobject_cast<ZigbeeNodeEndpointDeconz *>(getEndpoint(endpointId));
@ -323,7 +358,7 @@ void ZigbeeNodeDeconz::initEndpoints()
quint16 clusterId = 0;
stream >> clusterId;
if (!endpoint->hasInputCluster(static_cast<Zigbee::ClusterId>(clusterId))) {
endpoint->addInputCluster(new ZigbeeCluster(static_cast<Zigbee::ClusterId>(clusterId), ZigbeeCluster::Input, endpoint));
endpoint->addInputCluster(new ZigbeeCluster(m_network, this, endpoint, static_cast<Zigbee::ClusterId>(clusterId), ZigbeeCluster::Input, endpoint));
}
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
@ -335,7 +370,7 @@ void ZigbeeNodeDeconz::initEndpoints()
quint16 clusterId = 0;
stream >> clusterId;
if (!endpoint->hasOutputCluster(static_cast<Zigbee::ClusterId>(clusterId))) {
endpoint->addOutputCluster(new ZigbeeCluster(static_cast<Zigbee::ClusterId>(clusterId), ZigbeeCluster::Output, endpoint));
endpoint->addOutputCluster(new ZigbeeCluster(m_network, this, endpoint, static_cast<Zigbee::ClusterId>(clusterId), ZigbeeCluster::Output, endpoint));
}
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
}
@ -354,10 +389,9 @@ void ZigbeeNodeDeconz::initEndpoints()
void ZigbeeNodeDeconz::initBasicCluster()
{
// TODO
setState(StateInitialized);
}
void ZigbeeNodeDeconz::setClusterAttributeReport(const ZigbeeClusterAttributeReport &report)

View File

@ -50,6 +50,8 @@ public:
ZigbeeNetworkReply *requestActiveEndpoints();
ZigbeeNetworkReply *requestSimpleDescriptor(quint8 endpoint);
ZigbeeNetworkReply *requestLeaveNetwork(bool rejoin = false, bool removeChildren = false);
void leaveNetworkRequest(bool rejoin = false, bool removeChildren = false) override;
private:

View File

@ -36,20 +36,6 @@ ZigbeeNodeEndpointDeconz::ZigbeeNodeEndpointDeconz(ZigbeeNetworkDeconz *network,
}
ZigbeeNetworkReply *ZigbeeNodeEndpointDeconz::readAttribute(ZigbeeCluster *cluster, QList<quint16> attributes)
{
Q_UNUSED(cluster)
Q_UNUSED(attributes)
return nullptr;
}
ZigbeeNetworkReply *ZigbeeNodeEndpointDeconz::configureReporting(ZigbeeCluster *cluster, QList<ZigbeeClusterReportConfigurationRecord> reportConfigurations)
{
Q_UNUSED(cluster)
Q_UNUSED(reportConfigurations)
return nullptr;
}
void ZigbeeNodeEndpointDeconz::setClusterAttribute(Zigbee::ClusterId clusterId, const ZigbeeClusterAttribute &attribute)
{
Q_UNUSED(clusterId)

View File

@ -30,6 +30,7 @@
#include <QObject>
#include "zigbeenodeendpoint.h"
#include "zigbeeclusterlibrary.h"
class ZigbeeNodeDeconz;
class ZigbeeNetworkDeconz;
@ -43,9 +44,6 @@ class ZigbeeNodeEndpointDeconz : public ZigbeeNodeEndpoint
public:
explicit ZigbeeNodeEndpointDeconz(ZigbeeNetworkDeconz *network, ZigbeeNode *node, quint8 endpointId, QObject *parent = nullptr);
ZigbeeNetworkReply *readAttribute(ZigbeeCluster *cluster, QList<quint16> attributes) override;
ZigbeeNetworkReply *configureReporting(ZigbeeCluster *cluster, QList<ZigbeeClusterReportConfigurationRecord> reportConfigurations) override;
protected:
// Cluster commands
void setClusterAttribute(Zigbee::ClusterId clusterId, const ZigbeeClusterAttribute &attribute = ZigbeeClusterAttribute()) override;

View File

@ -10,23 +10,29 @@ SOURCES += \
deconz/zigbeenetworkdeconz.cpp \
deconz/zigbeenodedeconz.cpp \
deconz/zigbeenodeendpointdeconz.cpp \
nxp/interface/zigbeeinterface.cpp \
nxp/interface/zigbeeinterfacemessage.cpp \
nxp/interface/zigbeeinterfacerequest.cpp \
nxp/interface/zigbeeinterfacereply.cpp \
nxp/zigbeenetworknxp.cpp \
nxp/zigbeebridgecontrollernxp.cpp \
nxp/zigbeenodeendpointnxp.cpp \
nxp/zigbeenodenxp.cpp \
# nxp/interface/zigbeeinterface.cpp \
# nxp/interface/zigbeeinterfacemessage.cpp \
# nxp/interface/zigbeeinterfacerequest.cpp \
# nxp/interface/zigbeeinterfacereply.cpp \
# nxp/zigbeenetworknxp.cpp \
# nxp/zigbeebridgecontrollernxp.cpp \
# nxp/zigbeenodeendpointnxp.cpp \
# nxp/zigbeenodenxp.cpp \
zcl/zigbeeclusterbasic.cpp \
zdo/zigbeedeviceobject.cpp \
zdo/zigbeedeviceobjectreply.cpp \
zdo/zigbeedeviceprofilehandler.cpp \
zdo/zigbeedeviceprofile.cpp \
zigbeeadpu.cpp \
zigbeebridgecontroller.cpp \
zigbeechannelmask.cpp \
zigbeecluster.cpp \
zigbeeclusterattribute.cpp \
zigbeeclusterlibrary.cpp \
zigbeedeviceprofile.cpp \
zigbeeclusterlibraryreply.cpp \
zigbeemanufacturer.cpp \
zigbeenetwork.cpp \
zigbeenetworkdatabase.cpp \
zigbeenetworkkey.cpp \
zigbeenetworkmanager.cpp \
zigbee.cpp \
@ -39,6 +45,7 @@ SOURCES += \
zigbeenode.cpp \
zigbeeaddress.cpp \
HEADERS += \
deconz/interface/deconz.h \
deconz/interface/zigbeeinterfacedeconz.h \
@ -47,23 +54,29 @@ HEADERS += \
deconz/zigbeenetworkdeconz.h \
deconz/zigbeenodedeconz.h \
deconz/zigbeenodeendpointdeconz.h \
nxp/interface/zigbeeinterface.h \
nxp/interface/zigbeeinterfacemessage.h \
nxp/interface/zigbeeinterfacerequest.h \
nxp/interface/zigbeeinterfacereply.h \
nxp/zigbeenetworknxp.h \
nxp/zigbeebridgecontrollernxp.h \
nxp/zigbeenodeendpointnxp.h \
nxp/zigbeenodenxp.h \
# nxp/interface/zigbeeinterface.h \
# nxp/interface/zigbeeinterfacemessage.h \
# nxp/interface/zigbeeinterfacerequest.h \
# nxp/interface/zigbeeinterfacereply.h \
# nxp/zigbeenetworknxp.h \
# nxp/zigbeebridgecontrollernxp.h \
# nxp/zigbeenodeendpointnxp.h \
# nxp/zigbeenodenxp.h \
zcl/zigbeeclusterbasic.h \
zdo/zigbeedeviceobject.h \
zdo/zigbeedeviceobjectreply.h \
zdo/zigbeedeviceprofilehandler.h \
zdo/zigbeedeviceprofile.h \
zigbeeadpu.h \
zigbeebridgecontroller.h \
zigbeechannelmask.h \
zigbeecluster.h \
zigbeeclusterattribute.h \
zigbeeclusterlibrary.h \
zigbeedeviceprofile.h \
zigbeeclusterlibraryreply.h \
zigbeemanufacturer.h \
zigbeenetwork.h \
zigbeenetworkdatabase.h \
zigbeenetworkkey.h \
zigbeenetworkmanager.h \
zigbee.h \
@ -76,6 +89,7 @@ HEADERS += \
zigbeenode.h \
zigbeeaddress.h \
# install header file with relative subdirectory
for (header, HEADERS) {
path = $$[QT_INSTALL_PREFIX]/include/nymea-zigbee/$${dirname(header)}

View File

@ -32,4 +32,5 @@ Q_LOGGING_CATEGORY(dcZigbeeNode, "ZigbeeNode")
Q_LOGGING_CATEGORY(dcZigbeeCluster, "ZigbeeCluster")
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
Q_LOGGING_CATEGORY(dcZigbeeNetworkDatabase, "ZigbeeNetworkDatabase")
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")

View File

@ -36,6 +36,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNode)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeCluster)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNetworkDatabase)
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)
#endif // LOGGINGCATEGORY_H

View File

@ -0,0 +1,7 @@
#include "zigbeeclusterbasic.h"
ZigbeeClusterBasic::ZigbeeClusterBasic(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent) :
ZigbeeCluster(network, node, endpoint, Zigbee::ClusterIdBasic, direction, parent)
{
}

View File

@ -0,0 +1,51 @@
#ifndef ZIGBEECLUSTERBASIC_H
#define ZIGBEECLUSTERBASIC_H
#include <QObject>
#include "zigbeecluster.h"
class ZigbeeClusterBasic : public ZigbeeCluster
{
Q_OBJECT
public:
enum Attribute {
AttributeZclVersion = 0x0000, // Mandatory
AttributeAppVersion = 0x0001,
AttributeStackVersion = 0x0002,
AttributeHardwareVersion = 0x0003,
AttributeManufacturerName = 0x0004,
AttributeModelIdentifier = 0x0005,
AttributeDateCode = 0x0006, // ISO 8601 YYYYMMDD
AttributePowerSource = 0x0007, // Mandatory
AttributeLocationDescription = 0x0010,
AttributePhysicalEnvironment = 0x0011,
AttributeDeviceEnabled = 0x0012, // 0: disabled, 1: enabled
AttributeAlarmMask = 0x0013,
AttributeDisableLocalConfig = 0x0014,
AttributeSwBuildId = 0x4000
};
Q_ENUM(Attribute)
// From attribute 0x0007 power source
enum AttributePowerSourceValue {
AttributePowerSourceValueUnknown = 0x00,
AttributePowerSourceValueMainsSinglePhase = 0x01,
AttributePowerSourceValueMainsThreePhase = 0x02,
AttributePowerSourceValueBattery = 0x03,
AttributePowerSourceValueDcSource = 0x04,
AttributePowerSourceValueEmergencyMainsConstantlyPowered = 0x05,
AttributePowerSourceValueEmergencyMainsTransferSwitch = 0x06
};
Q_ENUM(AttributePowerSourceValue)
explicit ZigbeeClusterBasic(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr);
signals:
};
#endif // ZIGBEECLUSTERBASIC_H

View File

@ -0,0 +1,9 @@
#include "zigbeedeviceobject.h"
#include "zigbeenetwork.h"
ZigbeeDeviceObject::ZigbeeDeviceObject(ZigbeeNetwork *network, QObject *parent) :
QObject(parent),
m_network(network)
{
}

View File

@ -0,0 +1,21 @@
#ifndef ZIGBEEDEVICEOBJECT_H
#define ZIGBEEDEVICEOBJECT_H
#include <QObject>
class ZigbeeNetwork;
class ZigbeeDeviceObject : public QObject
{
Q_OBJECT
public:
explicit ZigbeeDeviceObject(ZigbeeNetwork *network, QObject *parent = nullptr);
private:
ZigbeeNetwork *m_network = nullptr;
signals:
};
#endif // ZIGBEEDEVICEOBJECT_H

View File

@ -0,0 +1,6 @@
#include "zigbeedeviceobjectreply.h"
ZigbeeDeviceObjectReply::ZigbeeDeviceObjectReply(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,16 @@
#ifndef ZIGBEEDEVICEOBJECTREPLY_H
#define ZIGBEEDEVICEOBJECTREPLY_H
#include <QObject>
class ZigbeeDeviceObjectReply : public QObject
{
Q_OBJECT
public:
explicit ZigbeeDeviceObjectReply(QObject *parent = nullptr);
signals:
};
#endif // ZIGBEEDEVICEOBJECTREPLY_H

View File

@ -45,6 +45,13 @@ class ZigbeeDeviceProfile
Q_GADGET
public:
enum Status {
StatusSuccess = 0x00,
StatusInvalidRequestType = 0x01,
StatusDeviceNotFound = 0x02
};
Q_ENUM(Status)
enum ZdoCommand {
/* Requests */
/*Device and service discovery */

View File

@ -0,0 +1,6 @@
#include "zigbeedeviceprofilehandler.h"
ZigbeeDeviceProfileHandler::ZigbeeDeviceProfileHandler(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,16 @@
#ifndef ZIGBEEDEVICEPROFILEHANDLER_H
#define ZIGBEEDEVICEPROFILEHANDLER_H
#include <QObject>
class ZigbeeDeviceProfileHandler : public QObject
{
Q_OBJECT
public:
explicit ZigbeeDeviceProfileHandler(QObject *parent = nullptr);
signals:
};
#endif // ZIGBEEDEVICEPROFILEHANDLER_H

View File

@ -26,11 +26,20 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zigbeeutils.h"
#include "zigbeenetwork.h"
#include "zigbeecluster.h"
#include "loggingcategory.h"
#include "zigbeenetworkreply.h"
#include "zigbeeclusterlibrary.h"
#include "zigbeenetworkrequest.h"
ZigbeeCluster::ZigbeeCluster(Zigbee::ClusterId clusterId, Direction direction, QObject *parent) :
#include <QDataStream>
ZigbeeCluster::ZigbeeCluster(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Zigbee::ClusterId clusterId, Direction direction, QObject *parent) :
QObject(parent),
m_network(network),
m_node(node),
m_endpoint(endpoint),
m_clusterId(clusterId),
m_direction(direction)
{
@ -83,6 +92,50 @@ void ZigbeeCluster::setAttribute(const ZigbeeClusterAttribute &attribute)
}
}
ZigbeeNetworkReply *ZigbeeCluster::readAttributes(QList<quint16> attributes)
{
// Build the request
ZigbeeNetworkRequest request;
request.setRequestId(m_network->generateSequenceNumber());
request.setDestinationAddressMode(Zigbee::DestinationAddressModeShortAddress);
request.setDestinationShortAddress(static_cast<quint16>(m_node->shortAddress()));
request.setProfileId(m_endpoint->profile());
request.setClusterId(m_clusterId);
request.setSourceEndpoint(m_endpoint->endpointId());
request.setRadius(10);
// Build ZCL frame
ZigbeeClusterLibrary::FrameControl frameControl;
frameControl.frameType = ZigbeeClusterLibrary::FrameTypeGlobal; // Note: for general commands always use global
frameControl.disableDefaultResponse = true;
// ZCL header
ZigbeeClusterLibrary::Header header;
header.frameControl = frameControl;
header.command = ZigbeeClusterLibrary::CommandReadAttributes;
header.transactionSequenceNumber = m_network->generateTranactionSequenceNumber();
// ZCL payload
QByteArray payload;
QDataStream stream(&payload, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
foreach (quint16 attribute, attributes) {
stream << attribute;
}
// Put them together
ZigbeeClusterLibrary::Frame frame;
frame.clusterId = m_clusterId;
frame.header = header;
frame.payload = payload;
request.setTxOptions(Zigbee::ZigbeeTxOptions(Zigbee::ZigbeeTxOptionAckTransmission));
request.setAsdu(ZigbeeClusterLibrary::buildFrame(frame));
qCDebug(dcZigbeeCluster()) << "Send read attributes request" << m_node << m_endpoint << this << attributes;
return m_network->sendRequest(request);
}
QDebug operator<<(QDebug debug, ZigbeeCluster *cluster)
{
debug.nospace().noquote() << "ZigbeeCluster("

View File

@ -31,6 +31,7 @@
#include <QObject>
#include "zigbee.h"
#include "zigbeeclusterlibrary.h"
#include "zigbeeclusterattribute.h"
struct ZigbeeClusterReportConfigurationRecord {
@ -53,6 +54,12 @@ typedef struct ZigbeeClusterAttributeReport {
QByteArray data;
} ZigbeeClusterAttributeReport;
class ZigbeeNode;
class ZigbeeNetwork;
class ZigbeeNodeEndpoint;
class ZigbeeNetworkReply;
class ZigbeeCluster : public QObject
{
Q_OBJECT
@ -189,7 +196,7 @@ public:
Q_ENUM(ColorControlClusterColorMode)
explicit ZigbeeCluster(Zigbee::ClusterId clusterId, Direction direction, QObject *parent = nullptr);
explicit ZigbeeCluster(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Zigbee::ClusterId clusterId, Direction direction, QObject *parent = nullptr);
Direction direction() const;
@ -204,13 +211,18 @@ public:
// FIXME: this should not be public
void setAttribute(const ZigbeeClusterAttribute &attribute);
private:
// ZCL global commands
ZigbeeNetworkReply *readAttributes(QList<quint16> attributes);
protected:
ZigbeeNetwork *m_network = nullptr;
ZigbeeNode *m_node = nullptr;
ZigbeeNodeEndpoint *m_endpoint= nullptr;
Zigbee::ClusterId m_clusterId = Zigbee::ClusterIdUnknown;
Direction m_direction = Input;
QHash<quint16, ZigbeeClusterAttribute> m_attributes;
protected:
signals:
void attributeChanged(const ZigbeeClusterAttribute &attribute);

View File

@ -93,7 +93,7 @@ QByteArray ZigbeeClusterLibrary::buildHeader(const ZigbeeClusterLibrary::Header
return headerData;
}
ZigbeeClusterLibrary::Frame ZigbeeClusterLibrary::parseFrameData(const QByteArray &frameData)
ZigbeeClusterLibrary::Frame ZigbeeClusterLibrary::parseFrameData(Zigbee::ClusterId clusterId, const QByteArray &frameData)
{
QDataStream stream(frameData);
stream.setByteOrder(QDataStream::LittleEndian);
@ -116,7 +116,6 @@ ZigbeeClusterLibrary::Frame ZigbeeClusterLibrary::parseFrameData(const QByteArra
stream >> header.transactionSequenceNumber;
offset += 1;
stream >> commandByte;
offset += 1;
@ -124,8 +123,9 @@ ZigbeeClusterLibrary::Frame ZigbeeClusterLibrary::parseFrameData(const QByteArra
offset += 1;
Frame frame;
frame.clusterId = clusterId;
frame.header = header;
frame.payload = frameData.right(frameData.length() - offset);
frame.payload = frameData.right(frameData.length() - offset - 1);
return frame;
}
@ -169,7 +169,7 @@ QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Header &header)
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Frame &frame)
{
debug.nospace() << "Zigbee Cluster Library Frame(";
debug.nospace() << "Zigbee Cluster Library Frame(" << frame.clusterId << ", ";
debug.nospace() << frame.header;
debug.nospace() << ZigbeeUtils::convertByteArrayToHexString(frame.payload) << ")";
return debug.space();

View File

@ -31,10 +31,13 @@
#include <QObject>
#include <QDebug>
#include "zigbee.h"
class ZigbeeClusterLibrary
{
Q_GADGET
public:
/* General ZCL commans */
enum Command {
CommandReadAttributes = 0x00,
CommandReadAttributesResponse = 0x01,
@ -90,6 +93,7 @@ public:
} ZclHeader;
typedef struct Frame {
Zigbee::ClusterId clusterId;
Header header;
QByteArray payload;
} Frame;
@ -100,7 +104,7 @@ public:
static QByteArray buildHeader(const Header &header);
static Frame parseFrameData(const QByteArray &frameData);
static Frame parseFrameData(Zigbee::ClusterId clusterId, const QByteArray &frameData);
static QByteArray buildFrame(const Frame &frame);
};

View File

@ -0,0 +1,24 @@
#include "zigbeeclusterlibraryreply.h"
ZigbeeNetworkRequest ZigbeeClusterLibraryReply::request() const
{
return m_request;
}
ZigbeeClusterLibrary::Frame ZigbeeClusterLibraryReply::requestFrame() const
{
return m_requestFrame;
}
quint8 ZigbeeClusterLibraryReply::transactionSequenceNumber() const
{
return m_requestFrame.header.transactionSequenceNumber;
}
ZigbeeClusterLibraryReply::ZigbeeClusterLibraryReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame requestFrame, QObject *parent) :
QObject(parent),
m_request(request),
m_requestFrame(requestFrame)
{
}

View File

@ -0,0 +1,35 @@
#ifndef ZIGBEECLUSTERLIBRARYREPLY_H
#define ZIGBEECLUSTERLIBRARYREPLY_H
#include <QObject>
#include "zigbeenetworkrequest.h"
#include "zigbeeclusterlibrary.h"
class ZigbeeClusterLibraryReply : public QObject
{
Q_OBJECT
friend class ZigbeeCluster;
public:
ZigbeeNetworkRequest request() const;
ZigbeeClusterLibrary::Frame requestFrame() const;
quint8 transactionSequenceNumber() const;
private:
explicit ZigbeeClusterLibraryReply(const ZigbeeNetworkRequest &request, ZigbeeClusterLibrary::Frame requestFrame, QObject *parent = nullptr);
ZigbeeNetworkRequest m_request;
ZigbeeClusterLibrary::Frame m_requestFrame;
ZigbeeClusterLibrary::Command m_expectedResponse;
ZigbeeClusterLibrary::Frame m_responseFrame;
signals:
void finished();
};
#endif // ZIGBEECLUSTERLIBRARYREPLY_H

View File

@ -29,9 +29,16 @@
#include "zigbeenetwork.h"
#include "loggingcategory.h"
#include <QSqlQuery>
ZigbeeNetwork::ZigbeeNetwork(QObject *parent) :
QObject(parent)
{
m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "zigbee");
m_db.setDatabaseName("");
qCDebug(dcZigbeeNetwork()) << "Opening zigbee network database" << m_db.databaseName();
}
@ -167,6 +174,16 @@ void ZigbeeNetwork::setPermitJoining(bool permitJoining)
setPermitJoiningInternal(permitJoining);
}
quint8 ZigbeeNetwork::generateSequenceNumber()
{
return m_sequenceNumber++;
}
quint8 ZigbeeNetwork::generateTranactionSequenceNumber()
{
return m_transactionSequenceNumber++;
}
QList<ZigbeeNode *> ZigbeeNetwork::nodes() const
{
return m_nodes;
@ -329,7 +346,7 @@ void ZigbeeNetwork::loadNetwork()
for (int n = 0; n < inputClustersCount; n ++) {
settings.setArrayIndex(n);
Zigbee::ClusterId clusterId = static_cast<Zigbee::ClusterId>(settings.value("clusterId", 0).toUInt());
ZigbeeCluster *cluster = new ZigbeeCluster(clusterId, ZigbeeCluster::Input, endpoint);
ZigbeeCluster *cluster = new ZigbeeCluster(this, node, endpoint, clusterId, ZigbeeCluster::Input, endpoint);
//qCDebug(dcZigbeeNetwork()) << "Created" << cluster;
endpoint->m_inputClusters.insert(clusterId, cluster);
}
@ -339,7 +356,7 @@ void ZigbeeNetwork::loadNetwork()
for (int n = 0; n < outputClustersCount; n ++) {
settings.setArrayIndex(n);
Zigbee::ClusterId clusterId = static_cast<Zigbee::ClusterId>(settings.value("clusterId", 0).toUInt());
ZigbeeCluster *cluster = new ZigbeeCluster(clusterId, ZigbeeCluster::Output, endpoint);
ZigbeeCluster *cluster = new ZigbeeCluster(this, node, endpoint, clusterId, ZigbeeCluster::Output, endpoint);
//qCDebug(dcZigbeeNetwork()) << "Created" << cluster;
endpoint->m_outputClusters.insert(clusterId, cluster);
}

View File

@ -31,6 +31,8 @@
#include <QObject>
#include <QSettings>
#include <QSqlDatabase>
#include "zigbeenode.h"
#include "zigbeechannelmask.h"
#include "zigbeebridgecontroller.h"
@ -94,6 +96,8 @@ public:
bool permitJoining() const;
void setPermitJoining(bool permitJoining);
quint8 generateSequenceNumber();
quint8 generateTranactionSequenceNumber();
// Network nodes
QList<ZigbeeNode *> nodes() const;
@ -106,6 +110,8 @@ public:
bool hasNode(quint16 shortAddress) const;
bool hasNode(const ZigbeeAddress &address) const;
virtual ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) = 0;
private:
State m_state = StateUninitialized;
@ -113,6 +119,9 @@ private:
QString m_serialPortName = "/dev/ttyUSB0";
qint32 m_serialBaudrate = 115200;
quint8 m_sequenceNumber = 0;
quint8 m_transactionSequenceNumber = 0;
// Network configurations
quint16 m_panId = 0;
quint64 m_extendedPanId = 0;
@ -120,10 +129,16 @@ private:
ZigbeeChannelMask m_channelMask = ZigbeeChannelMask(ZigbeeChannelMask::ChannelConfigurationAllChannels);
ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator;
// Network storage
QString m_settingsFileName = "/etc/nymea/nymea-zigbee.conf";
QList<ZigbeeNode *> m_nodes;
QList<ZigbeeNode *> m_uninitializedNodes;
QSqlDatabase m_db;
private:
bool initDB();
void addNodeInternally(ZigbeeNode *node);
void removeNodeInternally(ZigbeeNode *node);
@ -152,8 +167,6 @@ protected:
bool networkConfigurationAvailable() const;
virtual ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) = 0;
// Network reply methods
ZigbeeNetworkReply *createNetworkReply(const ZigbeeNetworkRequest &request = ZigbeeNetworkRequest());
void setReplyResponseData(ZigbeeNetworkReply *reply, const QByteArray &responseData);

View File

@ -0,0 +1,42 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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 "zigbeenetworkdatabase.h"
#include "loggingcategory.h"
ZigbeeNetworkDatabase::ZigbeeNetworkDatabase(const QString &databaseName, QObject *parent) : QObject(parent)
{
m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "zigbee");
m_db.setDatabaseName(databaseName);
qCDebug(dcZigbeeNetworkDatabase()) << "Opening zigbee network database" << m_db.databaseName();
if (!m_db.isValid()) {
qCWarning(dcZigbeeNetworkDatabase()) << "The zigbee network database is not valid" << m_db.databaseName();
// FIXME: create a new one
return;
}
}

View File

@ -0,0 +1,49 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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 ZIGBEENETWORKDATABASE_H
#define ZIGBEENETWORKDATABASE_H
#include <QObject>
#include <QSqlDatabase>
class ZigbeeNetworkDatabase : public QObject
{
Q_OBJECT
public:
explicit ZigbeeNetworkDatabase(const QString &databaseName, QObject *parent = nullptr);
private:
QSqlDatabase m_db;
signals:
};
#endif // ZIGBEENETWORKDATABASE_H

View File

@ -26,7 +26,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zigbeenetworkrequest.h"
#include "zigbeedeviceprofile.h"
#include "zdo/zigbeedeviceprofile.h"
#include "zigbeeutils.h"
ZigbeeNetworkRequest::ZigbeeNetworkRequest()

View File

@ -27,14 +27,16 @@
#include "zigbeenode.h"
#include "zigbeeutils.h"
#include "zigbeenetwork.h"
#include "loggingcategory.h"
#include <QDataStream>
ZigbeeNode::ZigbeeNode(QObject *parent) :
QObject(parent)
ZigbeeNode::ZigbeeNode(ZigbeeNetwork *network, QObject *parent) :
QObject(parent),
m_network(network)
{
m_deviceObject = new ZigbeeDeviceObject(m_network, this);
}
ZigbeeNode::State ZigbeeNode::state() const
@ -47,6 +49,11 @@ bool ZigbeeNode::connected() const
return m_connected;
}
ZigbeeDeviceObject *ZigbeeNode::deviceObject() const
{
return m_deviceObject;
}
quint16 ZigbeeNode::shortAddress() const
{
return m_shortAddress;
@ -248,95 +255,90 @@ void ZigbeeNode::setExtendedAddress(const ZigbeeAddress &extendedAddress)
m_extendedAddress = extendedAddress;
}
QByteArray ZigbeeNode::nodeDescriptorRawData() const
{
return m_nodeDescriptorRawData;
}
//void ZigbeeNode::setNodeDescriptorRawData(const QByteArray nodeDescriptorRawData)
//{
// m_nodeDescriptorRawData = nodeDescriptorRawData;
void ZigbeeNode::setNodeDescriptorRawData(const QByteArray nodeDescriptorRawData)
{
m_nodeDescriptorRawData = nodeDescriptorRawData;
// // Parse the raw data
// quint8 sequenceNumber = 0;
// quint8 status = 0;
// quint16 shortAddress = 0;
// quint16 manufacturerCode = 0;
// quint16 maximalRxSize = 0;
// quint16 maximalTxSize = 0;
// quint16 serverMask = 0;
// quint8 descriptorFlag = 0;
// quint8 macFlags = 0;
// quint8 maxBufferSize = 0;
// quint16 bitField = 0;
// Parse the raw data
quint8 sequenceNumber = 0;
quint8 status = 0;
quint16 shortAddress = 0;
quint16 manufacturerCode = 0;
quint16 maximalRxSize = 0;
quint16 maximalTxSize = 0;
quint16 serverMask = 0;
quint8 descriptorFlag = 0;
quint8 macFlags = 0;
quint8 maxBufferSize = 0;
quint16 bitField = 0;
// QDataStream stream(&m_nodeDescriptorRawData, QIODevice::ReadOnly);
// stream >> sequenceNumber;
// stream >> status;
// stream >> shortAddress;
// stream >> manufacturerCode;
// stream >> maximalRxSize;
// stream >> maximalTxSize;
// stream >> serverMask;
// stream >> descriptorFlag;
// stream >> macFlags;
// stream >> maxBufferSize;
// stream >> bitField;
QDataStream stream(&m_nodeDescriptorRawData, QIODevice::ReadOnly);
stream >> sequenceNumber;
stream >> status;
stream >> shortAddress;
stream >> manufacturerCode;
stream >> maximalRxSize;
stream >> maximalTxSize;
stream >> serverMask;
stream >> descriptorFlag;
stream >> macFlags;
stream >> maxBufferSize;
stream >> bitField;
// // Set node data
// m_manufacturerCode = manufacturerCode;
// m_maximumRxSize = maximalRxSize;
// m_maximumTxSize = maximalTxSize;
// m_maximumBufferSize = maxBufferSize;
// Set node data
m_manufacturerCode = manufacturerCode;
m_maximumRxSize = maximalRxSize;
m_maximumTxSize = maximalTxSize;
m_maximumBufferSize = maxBufferSize;
// setServerMask(serverMask);
// setMacCapabilitiesFlag(macFlags);
// setDescriptorFlag(descriptorFlag);
setServerMask(serverMask);
setMacCapabilitiesFlag(macFlags);
setDescriptorFlag(descriptorFlag);
// // Parse bit field
// // 0-2 Bit = logical type, 0 = coordinator, 1 = router, 2 = end device
// if (!ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
// m_nodeType = NodeTypeCoordinator;
// } else if (!ZigbeeUtils::checkBitUint16(bitField, 0) && ZigbeeUtils::checkBitUint16(bitField, 1)) {
// m_nodeType = NodeTypeRouter;
// } else if (ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
// m_nodeType = NodeTypeEndDevice;
// }
// Parse bit field
// 0-2 Bit = logical type, 0 = coordinator, 1 = router, 2 = end device
if (!ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
m_nodeType = NodeTypeCoordinator;
} else if (!ZigbeeUtils::checkBitUint16(bitField, 0) && ZigbeeUtils::checkBitUint16(bitField, 1)) {
m_nodeType = NodeTypeRouter;
} else if (ZigbeeUtils::checkBitUint16(bitField, 0) && !ZigbeeUtils::checkBitUint16(bitField, 1)) {
m_nodeType = NodeTypeEndDevice;
}
// m_complexDescriptorAvailable = (bitField >> 3) & 0x0001;
// m_userDescriptorAvailable = (bitField >> 4) & 0x0001;
m_complexDescriptorAvailable = (bitField >> 3) & 0x0001;
m_userDescriptorAvailable = (bitField >> 4) & 0x0001;
qCDebug(dcZigbeeNode()) << "Node descriptor:";
qCDebug(dcZigbeeNode()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
qCDebug(dcZigbeeNode()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
qCDebug(dcZigbeeNode()) << " Node type:" << nodeType();
qCDebug(dcZigbeeNode()) << " Short address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
qCDebug(dcZigbeeNode()) << " Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode);
qCDebug(dcZigbeeNode()) << " Maximum Rx size:" << ZigbeeUtils::convertUint16ToHexString(maximumRxSize());
qCDebug(dcZigbeeNode()) << " Maximum Tx size:" << ZigbeeUtils::convertUint16ToHexString(maximumTxSize());
qCDebug(dcZigbeeNode()) << " Maximum buffer size:" << ZigbeeUtils::convertByteToHexString(maximumBufferSize());
qCDebug(dcZigbeeNode()) << " Server mask:" << ZigbeeUtils::convertUint16ToHexString(serverMask);
qCDebug(dcZigbeeNode()) << " Primary Trust center:" << isPrimaryTrustCenter();
qCDebug(dcZigbeeNode()) << " Backup Trust center:" << isBackupTrustCenter();
qCDebug(dcZigbeeNode()) << " Primary Binding cache:" << isPrimaryBindingCache();
qCDebug(dcZigbeeNode()) << " Backup Binding cache:" << isBackupBindingCache();
qCDebug(dcZigbeeNode()) << " Primary Discovery cache:" << isPrimaryDiscoveryCache();
qCDebug(dcZigbeeNode()) << " Backup Discovery cache:" << isBackupDiscoveryCache();
qCDebug(dcZigbeeNode()) << " Network Manager:" << isNetworkManager();
qCDebug(dcZigbeeNode()) << " Descriptor flag:" << ZigbeeUtils::convertByteToHexString(descriptorFlag);
qCDebug(dcZigbeeNode()) << " Extended active endpoint list available:" << extendedActiveEndpointListAvailable();
qCDebug(dcZigbeeNode()) << " Extended simple descriptor list available:" << extendedSimpleDescriptorListAvailable();
qCDebug(dcZigbeeNode()) << " MAC flags:" << ZigbeeUtils::convertByteToHexString(macFlags);
qCDebug(dcZigbeeNode()) << " Alternate PAN coordinator:" << alternatePanCoordinator();
qCDebug(dcZigbeeNode()) << " Device type:" << deviceType();
qCDebug(dcZigbeeNode()) << " Power source flag main power:" << powerSourceFlagMainPower();
qCDebug(dcZigbeeNode()) << " Receiver on when idle:" << receiverOnWhenIdle();
qCDebug(dcZigbeeNode()) << " Security capability:" << securityCapability();
qCDebug(dcZigbeeNode()) << " Allocate address:" << allocateAddress();
qCDebug(dcZigbeeNode()) << " Bit field:" << ZigbeeUtils::convertUint16ToHexString(bitField);
qCDebug(dcZigbeeNode()) << " Complex desciptor available:" << complexDescriptorAvailable();
qCDebug(dcZigbeeNode()) << " User desciptor available:" << userDescriptorAvailable();
}
// qCDebug(dcZigbeeNode()) << "Node descriptor:";
// qCDebug(dcZigbeeNode()) << " Sequence number:" << ZigbeeUtils::convertByteToHexString(sequenceNumber);
// qCDebug(dcZigbeeNode()) << " Status:" << ZigbeeUtils::convertByteToHexString(status);
// qCDebug(dcZigbeeNode()) << " Node type:" << nodeType();
// qCDebug(dcZigbeeNode()) << " Short address:" << ZigbeeUtils::convertUint16ToHexString(shortAddress);
// qCDebug(dcZigbeeNode()) << " Manufacturer code:" << ZigbeeUtils::convertUint16ToHexString(manufacturerCode);
// qCDebug(dcZigbeeNode()) << " Maximum Rx size:" << ZigbeeUtils::convertUint16ToHexString(maximumRxSize());
// qCDebug(dcZigbeeNode()) << " Maximum Tx size:" << ZigbeeUtils::convertUint16ToHexString(maximumTxSize());
// qCDebug(dcZigbeeNode()) << " Maximum buffer size:" << ZigbeeUtils::convertByteToHexString(maximumBufferSize());
// qCDebug(dcZigbeeNode()) << " Server mask:" << ZigbeeUtils::convertUint16ToHexString(serverMask);
// qCDebug(dcZigbeeNode()) << " Primary Trust center:" << isPrimaryTrustCenter();
// qCDebug(dcZigbeeNode()) << " Backup Trust center:" << isBackupTrustCenter();
// qCDebug(dcZigbeeNode()) << " Primary Binding cache:" << isPrimaryBindingCache();
// qCDebug(dcZigbeeNode()) << " Backup Binding cache:" << isBackupBindingCache();
// qCDebug(dcZigbeeNode()) << " Primary Discovery cache:" << isPrimaryDiscoveryCache();
// qCDebug(dcZigbeeNode()) << " Backup Discovery cache:" << isBackupDiscoveryCache();
// qCDebug(dcZigbeeNode()) << " Network Manager:" << isNetworkManager();
// qCDebug(dcZigbeeNode()) << " Descriptor flag:" << ZigbeeUtils::convertByteToHexString(descriptorFlag);
// qCDebug(dcZigbeeNode()) << " Extended active endpoint list available:" << extendedActiveEndpointListAvailable();
// qCDebug(dcZigbeeNode()) << " Extended simple descriptor list available:" << extendedSimpleDescriptorListAvailable();
// qCDebug(dcZigbeeNode()) << " MAC flags:" << ZigbeeUtils::convertByteToHexString(macFlags);
// qCDebug(dcZigbeeNode()) << " Alternate PAN coordinator:" << alternatePanCoordinator();
// qCDebug(dcZigbeeNode()) << " Device type:" << deviceType();
// qCDebug(dcZigbeeNode()) << " Power source flag main power:" << powerSourceFlagMainPower();
// qCDebug(dcZigbeeNode()) << " Receiver on when idle:" << receiverOnWhenIdle();
// qCDebug(dcZigbeeNode()) << " Security capability:" << securityCapability();
// qCDebug(dcZigbeeNode()) << " Allocate address:" << allocateAddress();
// qCDebug(dcZigbeeNode()) << " Bit field:" << ZigbeeUtils::convertUint16ToHexString(bitField);
// qCDebug(dcZigbeeNode()) << " Complex desciptor available:" << complexDescriptorAvailable();
// qCDebug(dcZigbeeNode()) << " User desciptor available:" << userDescriptorAvailable();
//}
quint16 ZigbeeNode::serverMask() const
{
@ -448,14 +450,14 @@ void ZigbeeNode::setPowerDescriptorFlag(quint16 powerDescriptorFlag)
m_powerLevel = PowerLevelFull;
}
qCDebug(dcZigbeeNode()) << "Node power descriptor (" << ZigbeeUtils::convertUint16ToHexString(m_powerDescriptorFlag) << "):";
qCDebug(dcZigbeeNode()) << " Power mode:" << m_powerMode;
qCDebug(dcZigbeeNode()) << " Available power sources:";
foreach (const PowerSource &source, m_availablePowerSources) {
qCDebug(dcZigbeeNode()) << " " << source;
}
qCDebug(dcZigbeeNode()) << " Power source:" << m_powerSource;
qCDebug(dcZigbeeNode()) << " Power level:" << m_powerLevel;
// qCDebug(dcZigbeeNode()) << "Node power descriptor (" << ZigbeeUtils::convertUint16ToHexString(m_powerDescriptorFlag) << "):";
// qCDebug(dcZigbeeNode()) << " Power mode:" << m_powerMode;
// qCDebug(dcZigbeeNode()) << " Available power sources:";
// foreach (const PowerSource &source, m_availablePowerSources) {
// qCDebug(dcZigbeeNode()) << " " << source;
// }
// qCDebug(dcZigbeeNode()) << " Power source:" << m_powerSource;
// qCDebug(dcZigbeeNode()) << " Power level:" << m_powerLevel;
}
void ZigbeeNode::startInitialization()

View File

@ -33,6 +33,9 @@
#include "zigbee.h"
#include "zigbeeaddress.h"
#include "zigbeenodeendpoint.h"
#include "zdo/zigbeedeviceobject.h"
class ZigbeeNetwork;
class ZigbeeNode : public QObject
{
@ -100,6 +103,8 @@ public:
State state() const;
bool connected() const;
ZigbeeDeviceObject *deviceObject() const;
quint16 shortAddress() const;
ZigbeeAddress extendedAddress() const;
@ -190,8 +195,10 @@ private:
virtual void setClusterAttributeReport(const ZigbeeClusterAttributeReport &report) = 0;
protected:
ZigbeeNode(QObject *parent = nullptr);
ZigbeeNode(ZigbeeNetwork *network, QObject *parent = nullptr);
ZigbeeNetwork *m_network;
ZigbeeDeviceObject *m_deviceObject = nullptr;
QList<ZigbeeNodeEndpoint *> m_endpoints;
// Node descriptor information
@ -214,10 +221,6 @@ protected:
void setShortAddress(const quint16 &shortAddress);
void setExtendedAddress(const ZigbeeAddress &extendedAddress);
// Note: node descriptor properties (raw data for settings)
QByteArray nodeDescriptorRawData() const;
void setNodeDescriptorRawData(const QByteArray nodeDescriptorRawData);
quint16 serverMask() const;
void setServerMask(quint16 serverMask);

View File

@ -73,36 +73,6 @@ public:
ZigbeeCluster *getOutputCluster(Zigbee::ClusterId clusterId) const;
bool hasOutputCluster(Zigbee::ClusterId clusterId) const;
// Attribute methods
virtual ZigbeeNetworkReply *readAttribute(ZigbeeCluster *cluster, QList<quint16> attributes) = 0;
virtual ZigbeeNetworkReply *configureReporting(ZigbeeCluster *cluster, QList<ZigbeeClusterReportConfigurationRecord> reportConfigurations) = 0;
// Identify
virtual ZigbeeNetworkReply *identify(quint16 seconds);
// Reset
virtual ZigbeeNetworkReply *factoryReset();
// Binding
virtual ZigbeeNetworkReply *bindGroup(Zigbee::ClusterId clusterId, quint16 destinationAddress, quint8 destinationEndpoint);
virtual ZigbeeNetworkReply *bindUnicast(Zigbee::ClusterId clusterId, const ZigbeeAddress &destinationAddress, quint8 destinationEndpoint);
// Cluster commands
virtual ZigbeeNetworkReply *sendOnOffClusterCommand(ZigbeeCluster::OnOffClusterCommand command);
// Group commands
virtual ZigbeeNetworkReply *addGroup(quint8 destinationEndpoint, quint16 groupAddress);
// Level commands
virtual ZigbeeNetworkReply *sendLevelCommand(ZigbeeCluster::LevelClusterCommand command, quint8 level, bool triggersOnOff, quint16 transitionTime);
// Color commands
virtual ZigbeeNetworkReply *sendMoveToColorTemperature(quint16 colourTemperature, quint16 transitionTime);
virtual ZigbeeNetworkReply *sendMoveToColor(double x, double y, quint16 transitionTime);
virtual ZigbeeNetworkReply *sendMoveToHueSaturation(quint8 hue, quint8 saturation, quint16 transitionTime);
virtual ZigbeeNetworkReply *sendMoveToHue(quint8 hue, quint16 transitionTime);
virtual ZigbeeNetworkReply *sendMoveToSaturation(quint8 saturation, quint16 transitionTime);
private:
ZigbeeNode *m_node = nullptr;
quint8 m_endpointId = 0;
@ -139,6 +109,7 @@ signals:
void manufacturerNameChanged(const QString &manufacturerName);
void modelIdentifierChanged(const QString &modelIdentifier);
void softwareBuildIdChanged(const QString &softwareBuildId);
};
QDebug operator<<(QDebug debug, ZigbeeNodeEndpoint *endpoint);