Add ZCL basics
This commit is contained in:
parent
882023198a
commit
3e8da8ee26
@ -38,7 +38,7 @@ ZigbeeInterfaceDeconz::ZigbeeInterfaceDeconz(QObject *parent) : QObject(parent)
|
|||||||
{
|
{
|
||||||
m_reconnectTimer = new QTimer(this);
|
m_reconnectTimer = new QTimer(this);
|
||||||
m_reconnectTimer->setSingleShot(true);
|
m_reconnectTimer->setSingleShot(true);
|
||||||
m_reconnectTimer->setInterval(2000);
|
m_reconnectTimer->setInterval(5000);
|
||||||
|
|
||||||
connect(m_reconnectTimer, &QTimer::timeout, this, &ZigbeeInterfaceDeconz::onReconnectTimeout);
|
connect(m_reconnectTimer, &QTimer::timeout, this, &ZigbeeInterfaceDeconz::onReconnectTimeout);
|
||||||
}
|
}
|
||||||
@ -122,11 +122,12 @@ void ZigbeeInterfaceDeconz::setAvailable(bool available)
|
|||||||
if (m_available == available)
|
if (m_available == available)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Clear the data buffer in any case
|
||||||
|
if (m_available)
|
||||||
|
m_dataBuffer.clear();
|
||||||
|
|
||||||
m_available = available;
|
m_available = available;
|
||||||
emit availableChanged(m_available);
|
emit availableChanged(m_available);
|
||||||
|
|
||||||
// Clear the data buffer in any case
|
|
||||||
m_dataBuffer.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeInterfaceDeconz::onReconnectTimeout()
|
void ZigbeeInterfaceDeconz::onReconnectTimeout()
|
||||||
@ -137,7 +138,6 @@ void ZigbeeInterfaceDeconz::onReconnectTimeout()
|
|||||||
m_reconnectTimer->start();
|
m_reconnectTimer->start();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcZigbeeInterface()) << "Interface reconnected successfully on" << m_serialPort->portName() << m_serialPort->baudRate();
|
qCDebug(dcZigbeeInterface()) << "Interface reconnected successfully on" << m_serialPort->portName() << m_serialPort->baudRate();
|
||||||
m_serialPort->clear();
|
|
||||||
setAvailable(true);
|
setAvailable(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,13 +232,13 @@ void ZigbeeInterfaceDeconz::sendPackage(const QByteArray &package)
|
|||||||
|
|
||||||
bool ZigbeeInterfaceDeconz::enable(const QString &serialPort, qint32 baudrate)
|
bool ZigbeeInterfaceDeconz::enable(const QString &serialPort, qint32 baudrate)
|
||||||
{
|
{
|
||||||
|
qCDebug(dcZigbeeInterface()) << "Start UART interface " << serialPort << baudrate;
|
||||||
|
|
||||||
if (m_serialPort) {
|
if (m_serialPort) {
|
||||||
delete m_serialPort;
|
delete m_serialPort;
|
||||||
m_serialPort = nullptr;
|
m_serialPort = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAvailable(false);
|
|
||||||
|
|
||||||
m_serialPort = new QSerialPort(serialPort, this);
|
m_serialPort = new QSerialPort(serialPort, this);
|
||||||
m_serialPort->setBaudRate(baudrate);
|
m_serialPort->setBaudRate(baudrate);
|
||||||
m_serialPort->setDataBits(QSerialPort::Data8);
|
m_serialPort->setDataBits(QSerialPort::Data8);
|
||||||
@ -260,6 +260,20 @@ bool ZigbeeInterfaceDeconz::enable(const QString &serialPort, qint32 baudrate)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeInterfaceDeconz::reconnectController()
|
||||||
|
{
|
||||||
|
if (!m_serialPort)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_serialPort->isOpen())
|
||||||
|
m_serialPort->close();
|
||||||
|
|
||||||
|
delete m_serialPort;
|
||||||
|
m_serialPort = nullptr;
|
||||||
|
setAvailable(false);
|
||||||
|
m_reconnectTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeInterfaceDeconz::disable()
|
void ZigbeeInterfaceDeconz::disable()
|
||||||
{
|
{
|
||||||
if (!m_serialPort)
|
if (!m_serialPort)
|
||||||
|
|||||||
@ -75,6 +75,7 @@ public slots:
|
|||||||
void sendPackage(const QByteArray &package);
|
void sendPackage(const QByteArray &package);
|
||||||
|
|
||||||
bool enable(const QString &serialPort = "/dev/ttyS0", qint32 baudrate = 115200);
|
bool enable(const QString &serialPort = "/dev/ttyS0", qint32 baudrate = 115200);
|
||||||
|
void reconnectController();
|
||||||
void disable();
|
void disable();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -42,7 +42,7 @@ ZigbeeBridgeControllerDeconz::ZigbeeBridgeControllerDeconz(QObject *parent) :
|
|||||||
|
|
||||||
m_watchdogTimer = new QTimer(this);
|
m_watchdogTimer = new QTimer(this);
|
||||||
m_watchdogTimer->setSingleShot(false);
|
m_watchdogTimer->setSingleShot(false);
|
||||||
m_watchdogTimer->setInterval(m_watchdogResetTimout * 1000); // Set the watchdog to 85 seconds, reset every 60 s
|
m_watchdogTimer->setInterval(m_watchdogResetTimout * 1000);
|
||||||
connect(m_watchdogTimer, &QTimer::timeout, this, &ZigbeeBridgeControllerDeconz::resetControllerWatchdog);
|
connect(m_watchdogTimer, &QTimer::timeout, this, &ZigbeeBridgeControllerDeconz::resetControllerWatchdog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,6 +684,9 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the watchdog in any case
|
||||||
|
resetControllerWatchdog();
|
||||||
|
|
||||||
// Read watchdog timeout
|
// Read watchdog timeout
|
||||||
ZigbeeInterfaceDeconzReply *replyWatchdogTimeout = requestReadParameter(Deconz::ParameterWatchdogTtl);
|
ZigbeeInterfaceDeconzReply *replyWatchdogTimeout = requestReadParameter(Deconz::ParameterWatchdogTtl);
|
||||||
connect(replyWatchdogTimeout, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyWatchdogTimeout](){
|
connect(replyWatchdogTimeout, &ZigbeeInterfaceDeconzReply::finished, this, [this, readNetworkParametersReply, replyWatchdogTimeout](){
|
||||||
@ -704,11 +707,6 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
<< "finished successfully";
|
<< "finished successfully";
|
||||||
qCDebug(dcZigbeeController()) << "Watchdog timeout:" << m_networkConfiguration.watchdogTimeout;
|
qCDebug(dcZigbeeController()) << "Watchdog timeout:" << m_networkConfiguration.watchdogTimeout;
|
||||||
|
|
||||||
// Note: this value describes how much seconds are left until the watchdog triggers. Reset it right the way
|
|
||||||
if (watchdogTimeout < 15) {
|
|
||||||
resetControllerWatchdog();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
||||||
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
||||||
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
||||||
@ -887,10 +885,8 @@ void ZigbeeBridgeControllerDeconz::processDataConfirm(const QByteArray &data)
|
|||||||
|
|
||||||
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
if (available) {
|
qCDebug(dcZigbeeController()) << "Interface available changed" << available;
|
||||||
// FIXME: only start if the protocol version is >= 0x0108
|
if (!available) {
|
||||||
m_watchdogTimer->start();
|
|
||||||
} else {
|
|
||||||
// Clean up any pending replies
|
// Clean up any pending replies
|
||||||
foreach (quint8 id, m_pendingReplies.keys()) {
|
foreach (quint8 id, m_pendingReplies.keys()) {
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_pendingReplies.take(id);
|
ZigbeeInterfaceDeconzReply *reply = m_pendingReplies.take(id);
|
||||||
@ -940,6 +936,7 @@ void ZigbeeBridgeControllerDeconz::onInterfacePackageReceived(const QByteArray &
|
|||||||
}
|
}
|
||||||
case Deconz::CommandMacPoll: {
|
case Deconz::CommandMacPoll: {
|
||||||
// FIXME: parse the data and print info
|
// FIXME: parse the data and print info
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Deconz::CommandSimplifiedBeacon: {
|
case Deconz::CommandSimplifiedBeacon: {
|
||||||
@ -961,12 +958,13 @@ void ZigbeeBridgeControllerDeconz::resetControllerWatchdog()
|
|||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << m_watchdogTimeout;
|
stream << m_watchdogTimeout;
|
||||||
ZigbeeInterfaceDeconzReply *reply = requestWriteParameter(Deconz::ParameterWatchdogTtl, parameterData);
|
ZigbeeInterfaceDeconzReply *reply = requestWriteParameter(Deconz::ParameterWatchdogTtl, parameterData);
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not reset the application watchdog on the deCONZ controller." << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not reset the application watchdog on the deCONZ controller." << reply->statusCode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qCDebug(dcZigbeeController()) << "Reset application watchdog on the deCONZ controller successfully";
|
qCDebug(dcZigbeeController()) << "Reset application watchdog on the deCONZ controller successfully";
|
||||||
|
m_watchdogTimer->start();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -134,8 +134,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
ZigbeeInterfaceDeconz *m_interface = nullptr;
|
ZigbeeInterfaceDeconz *m_interface = nullptr;
|
||||||
quint8 m_sequenceNumber = 0;
|
quint8 m_sequenceNumber = 0;
|
||||||
quint32 m_watchdogTimeout = 85;
|
quint32 m_watchdogTimeout = 300;
|
||||||
int m_watchdogResetTimout = 60;
|
int m_watchdogResetTimout = 280;
|
||||||
QHash<quint8, ZigbeeInterfaceDeconzReply *> m_pendingReplies;
|
QHash<quint8, ZigbeeInterfaceDeconzReply *> m_pendingReplies;
|
||||||
DeconzNetworkConfiguration m_networkConfiguration;
|
DeconzNetworkConfiguration m_networkConfiguration;
|
||||||
Deconz::NetworkState m_networkState = Deconz::NetworkStateOffline;
|
Deconz::NetworkState m_networkState = Deconz::NetworkStateOffline;
|
||||||
|
|||||||
@ -54,8 +54,9 @@ ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(QObject *parent) :
|
|||||||
|
|
||||||
ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
||||||
{
|
{
|
||||||
if (m_controller)
|
if (m_controller) {
|
||||||
return qobject_cast<ZigbeeBridgeController *>(m_controller);
|
return qobject_cast<ZigbeeBridgeController *>(m_controller);
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -222,7 +223,7 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configured security mode successfully";
|
qCDebug(dcZigbeeNetwork()) << "Configured security mode successfully. SQN:" << reply->sequenceNumber();
|
||||||
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Configure network key" << securityConfiguration().networkKey().toString();
|
qCDebug(dcZigbeeNetwork()) << "Configure network key" << securityConfiguration().networkKey().toString();
|
||||||
@ -279,11 +280,16 @@ void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetwo
|
|||||||
setChannel(m_controller->networkConfiguration().currentChannel);
|
setChannel(m_controller->networkConfiguration().currentChannel);
|
||||||
|
|
||||||
setCreateNetworkState(CreateNetworkStateInitializeCoordinatorNode);
|
setCreateNetworkState(CreateNetworkStateInitializeCoordinatorNode);
|
||||||
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CreateNetworkStateInitializeCoordinatorNode: {
|
case CreateNetworkStateInitializeCoordinatorNode: {
|
||||||
|
if (m_coordinatorNode) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
|
||||||
|
setState(StateRunning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeNodeDeconz *coordinatorNode = qobject_cast<ZigbeeNodeDeconz *>(createNode(this));
|
ZigbeeNodeDeconz *coordinatorNode = qobject_cast<ZigbeeNodeDeconz *>(createNode(this));
|
||||||
coordinatorNode->setShortAddress(m_controller->networkConfiguration().shortAddress);
|
coordinatorNode->setShortAddress(m_controller->networkConfiguration().shortAddress);
|
||||||
coordinatorNode->setExtendedAddress(m_controller->networkConfiguration().ieeeAddress);
|
coordinatorNode->setExtendedAddress(m_controller->networkConfiguration().ieeeAddress);
|
||||||
@ -340,7 +346,7 @@ void ZigbeeNetworkDeconz::handleZigbeeDeviceProfileIndication(const DeconzApsDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qCWarning(dcZigbeeNetwork()) << "Unhandled ZDO indication" << indication;
|
qCWarning(dcZigbeeNetwork()) << "FIXME: Unhandled ZDO indication" << indication;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNode *ZigbeeNetworkDeconz::createNode(QObject *parent)
|
ZigbeeNode *ZigbeeNetworkDeconz::createNode(QObject *parent)
|
||||||
@ -400,10 +406,9 @@ void ZigbeeNetworkDeconz::setPermitJoiningInternal(bool permitJoining)
|
|||||||
|
|
||||||
void ZigbeeNetworkDeconz::startNetworkInternally()
|
void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetwork()) << "Start network internally";
|
qCDebug(dcZigbeeNetwork()) << "Start zigbee network internally";
|
||||||
|
|
||||||
m_createNewNetwork = false;
|
m_createNewNetwork = false;
|
||||||
|
|
||||||
// Check if we have to create a pan ID and select the channel
|
// Check if we have to create a pan ID and select the channel
|
||||||
if (panId() == 0) {
|
if (panId() == 0) {
|
||||||
m_createNewNetwork = true;
|
m_createNewNetwork = true;
|
||||||
@ -411,15 +416,17 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
//qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
//qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (securityConfiguration().networkKey().isNull()) {
|
// Note: we cannot read or write the network key here.
|
||||||
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";
|
// if (securityConfiguration().networkKey().isNull()) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().globalTrustCenterLinkKey() << "global trust center link key";
|
// 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 firmware version
|
||||||
// - Read the network configuration parameters
|
// - Read the network configuration parameters
|
||||||
@ -429,6 +436,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
// - If network running and configurations match, we are done
|
// - If network running and configurations match, we are done
|
||||||
|
|
||||||
// Read the firmware version
|
// Read the firmware version
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Reading current firmware version...";
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
@ -436,7 +444,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
// FIXME: set an appropriate error
|
// FIXME: set an appropriate error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qCDebug(dcZigbeeNetwork()) << "Version request finished" << reply->statusCode() << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
qCDebug(dcZigbeeNetwork()) << "Version request finished successfully" << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
||||||
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
||||||
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
||||||
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
||||||
@ -445,6 +453,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
||||||
|
|
||||||
// Read all network parameters
|
// Read all network parameters
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Start reading controller network parameters...";
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply, firmwareVersion](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply, firmwareVersion](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
@ -456,11 +465,12 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
||||||
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion >> 8 & 0xFF)
|
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion >> 8 & 0xFF)
|
||||||
.arg(m_controller->networkConfiguration().protocolVersion & 0xFF);
|
.arg(m_controller->networkConfiguration().protocolVersion & 0xFF);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Controller API protocol version" << ZigbeeUtils::convertUint16ToHexString(m_controller->networkConfiguration().protocolVersion) << protocolVersion;
|
||||||
|
|
||||||
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(firmwareVersion).arg(protocolVersion));
|
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(firmwareVersion).arg(protocolVersion));
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << m_controller->networkConfiguration();
|
qCDebug(dcZigbeeNetwork()) << m_controller->networkConfiguration();
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Reading current network state";
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
@ -469,29 +479,34 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Read device state finished successfully. SQN:" << reply->sequenceNumber();
|
|
||||||
QDataStream stream(reply->responseData());
|
QDataStream stream(reply->responseData());
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 deviceStateFlag = 0;
|
quint8 deviceStateFlag = 0;
|
||||||
stream >> deviceStateFlag;
|
stream >> deviceStateFlag;
|
||||||
|
DeconzDeviceState deviceState = m_controller->parseDeviceStateFlag(deviceStateFlag);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << deviceState;
|
||||||
|
|
||||||
// Update the device state in the controller
|
// Update the device state in the controller
|
||||||
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
m_controller->processDeviceState(deviceState);
|
||||||
|
|
||||||
if (m_createNewNetwork) {
|
if (m_createNewNetwork) {
|
||||||
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
|
||||||
// Set offline
|
// Set offline
|
||||||
// Write configurations
|
// Write configurations
|
||||||
// Set online
|
// Set online
|
||||||
// Read configurations
|
// Read configurations
|
||||||
// Create and initialize coordinator node
|
// Create and initialize coordinator node
|
||||||
// Done. Save network
|
// Done. Save network
|
||||||
|
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
||||||
} else {
|
} else {
|
||||||
// Get the network state and start the network if required
|
// Get the network state and start the network if required
|
||||||
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
||||||
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
||||||
setState(StateRunning);
|
setState(StateRunning);
|
||||||
|
} else if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "The network is offline. Lets start it";
|
||||||
|
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
||||||
} else {
|
} else {
|
||||||
startNetwork();
|
// The network is not running yet, lets wait for the state changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -501,9 +516,8 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
|||||||
|
|
||||||
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetwork()) << "Hardware controller is" << (available ? "now available" : "not available");
|
|
||||||
|
|
||||||
if (!available) {
|
if (!available) {
|
||||||
|
qCWarning(dcZigbeeNetwork()) << "Hardware controller is not available any more.";
|
||||||
setError(ErrorHardwareUnavailable);
|
setError(ErrorHardwareUnavailable);
|
||||||
m_permitJoining = false;
|
m_permitJoining = false;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
emit permitJoiningChanged(m_permitJoining);
|
||||||
@ -513,6 +527,7 @@ void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
|||||||
m_permitJoining = false;
|
m_permitJoining = false;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
emit permitJoiningChanged(m_permitJoining);
|
||||||
setState(StateStarting);
|
setState(StateStarting);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Hardware controller is now available.";
|
||||||
startNetworkInternally();
|
startNetworkInternally();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,8 +74,14 @@ private:
|
|||||||
QTimer *m_pollNetworkStateTimer = nullptr;
|
QTimer *m_pollNetworkStateTimer = nullptr;
|
||||||
void setCreateNetworkState(CreateNetworkState state);
|
void setCreateNetworkState(CreateNetworkState state);
|
||||||
|
|
||||||
|
// ZDO
|
||||||
void handleZigbeeDeviceProfileIndication(const DeconzApsDataIndication &indication);
|
void handleZigbeeDeviceProfileIndication(const DeconzApsDataIndication &indication);
|
||||||
|
|
||||||
|
// ZZL
|
||||||
|
|
||||||
|
// HA
|
||||||
|
|
||||||
|
// GP
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ZigbeeNode *createNode(QObject *parent) override;
|
ZigbeeNode *createNode(QObject *parent) override;
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
#include "zigbeenodedeconz.h"
|
#include "zigbeenodedeconz.h"
|
||||||
#include "zigbeedeviceprofile.h"
|
#include "zigbeedeviceprofile.h"
|
||||||
#include "zigbeenetworkdeconz.h"
|
#include "zigbeenetworkdeconz.h"
|
||||||
|
#include "zigbeenodeendpointdeconz.h"
|
||||||
|
|
||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
@ -142,26 +144,8 @@ void ZigbeeNodeDeconz::leaveNetworkRequest(bool rejoin, bool removeChildren)
|
|||||||
Q_UNUSED(removeChildren)
|
Q_UNUSED(removeChildren)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNodeDeconz::setClusterAttributeReport(const ZigbeeClusterAttributeReport &report)
|
void ZigbeeNodeDeconz::initNodeDescriptor()
|
||||||
{
|
{
|
||||||
Q_UNUSED(report)
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigbeeNodeDeconz::startInitialization()
|
|
||||||
{
|
|
||||||
setState(StateInitializing);
|
|
||||||
|
|
||||||
/* Node initialisation steps (sequentially)
|
|
||||||
* - Node descriptor
|
|
||||||
* - Power descriptor
|
|
||||||
* - Active endpoints
|
|
||||||
* - for each endpoint do:
|
|
||||||
* - Simple descriptor request
|
|
||||||
* - for each endpoint
|
|
||||||
* - read basic cluster
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
ZigbeeNetworkReply *reply = requestNodeDescriptor();
|
ZigbeeNetworkReply *reply = requestNodeDescriptor();
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
||||||
// TODO: check reply error
|
// TODO: check reply error
|
||||||
@ -231,123 +215,181 @@ void ZigbeeNodeDeconz::startInitialization()
|
|||||||
qCDebug(dcZigbeeNode()) << " Allocate address:" << allocateAddress();
|
qCDebug(dcZigbeeNode()) << " Allocate address:" << allocateAddress();
|
||||||
|
|
||||||
|
|
||||||
// Power descriptor
|
// Continue with the power descriptor
|
||||||
ZigbeeNetworkReply *reply = requestPowerDescriptor();
|
initPowerDescriptor();
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
});
|
||||||
// TODO: check reply error
|
}
|
||||||
|
|
||||||
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
void ZigbeeNodeDeconz::initPowerDescriptor()
|
||||||
qCDebug(dcZigbeeNode()) << "Power descriptor request finished" << this << adpu;
|
{
|
||||||
QDataStream stream(adpu.payload);
|
ZigbeeNetworkReply *reply = requestPowerDescriptor();
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
||||||
quint16 powerDescriptorFlag = 0;
|
// TODO: check reply error
|
||||||
stream >> powerDescriptorFlag;
|
|
||||||
setPowerDescriptorFlag(powerDescriptorFlag);
|
|
||||||
|
|
||||||
|
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
||||||
|
qCDebug(dcZigbeeNode()) << "Power descriptor request finished" << this << adpu;
|
||||||
|
QDataStream stream(adpu.payload);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint16 powerDescriptorFlag = 0;
|
||||||
|
stream >> powerDescriptorFlag;
|
||||||
|
setPowerDescriptorFlag(powerDescriptorFlag);
|
||||||
|
|
||||||
ZigbeeNetworkReply *reply = requestActiveEndpoints();
|
// Continue with endpoint fetching
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
initEndpoints();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNodeDeconz::initEndpoints()
|
||||||
|
{
|
||||||
|
ZigbeeNetworkReply *reply = requestActiveEndpoints();
|
||||||
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply](){
|
||||||
|
// TODO: check reply error
|
||||||
|
|
||||||
|
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
||||||
|
qCDebug(dcZigbeeNode()) << "Active endpoints request finished" << this << adpu;
|
||||||
|
QDataStream stream(adpu.payload);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint8 endpointCount = 0;
|
||||||
|
m_uninitializedEndpoints.clear();
|
||||||
|
stream >> endpointCount;
|
||||||
|
for (int i = 0; i < endpointCount; i++) {
|
||||||
|
quint8 endpoint = 0;
|
||||||
|
stream >> endpoint;
|
||||||
|
m_uninitializedEndpoints.append(endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNode()) << "Endpoints" << endpointCount;
|
||||||
|
for (int i = 0; i < m_uninitializedEndpoints.count(); i++) {
|
||||||
|
qCDebug(dcZigbeeNode()) << " -" << ZigbeeUtils::convertByteToHexString(m_uninitializedEndpoints.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read simple descriptor for each endpoint
|
||||||
|
if (m_uninitializedEndpoints.isEmpty()) {
|
||||||
|
initBasicCluster();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m_uninitializedEndpoints.count(); i++) {
|
||||||
|
quint8 endpointId = m_uninitializedEndpoints.at(i);
|
||||||
|
qCDebug(dcZigbeeNode()) << "Read simple descriptor of endpoint" << ZigbeeUtils::convertByteToHexString(endpointId);
|
||||||
|
ZigbeeNetworkReply *reply = requestSimpleDescriptor(endpointId);
|
||||||
|
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, endpointId](){
|
||||||
// TODO: check reply error
|
// TODO: check reply error
|
||||||
|
|
||||||
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
||||||
qCDebug(dcZigbeeNode()) << "Active endpoints request finished" << this << adpu;
|
qCDebug(dcZigbeeNode()) << "Simple descriptor request finished" << this << endpointId << adpu;
|
||||||
|
|
||||||
QDataStream stream(adpu.payload);
|
QDataStream stream(adpu.payload);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 endpointCount = 0;
|
quint8 length = 0;
|
||||||
m_uninitializedEndpoints.clear();
|
quint8 endpointId = 0;
|
||||||
stream >> endpointCount;
|
quint16 profileId = 0;
|
||||||
for (int i = 0; i < endpointCount; i++) {
|
quint16 deviceId = 0;
|
||||||
quint8 endpoint = 0;
|
quint8 deviceVersion = 0;
|
||||||
stream >> endpoint;
|
quint8 inputClusterCount = 0;
|
||||||
m_uninitializedEndpoints.append(endpoint);
|
quint8 outputClusterCount = 0;
|
||||||
|
|
||||||
|
QList<quint16> inputClusters;
|
||||||
|
QList<quint16> outputClusters;
|
||||||
|
|
||||||
|
stream >> length >> endpointId >> profileId >> deviceId >> deviceVersion >> inputClusterCount;
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNode()) << "Node endpoint simple descriptor:";
|
||||||
|
qCDebug(dcZigbeeNode()) << " Lenght:" << ZigbeeUtils::convertByteToHexString(length);
|
||||||
|
qCDebug(dcZigbeeNode()) << " End Point:" << ZigbeeUtils::convertByteToHexString(endpointId);
|
||||||
|
qCDebug(dcZigbeeNode()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast<Zigbee::ZigbeeProfile>(profileId));
|
||||||
|
if (profileId == Zigbee::ZigbeeProfileLightLink) {
|
||||||
|
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::LightLinkDevice>(deviceId);
|
||||||
|
} else if (profileId == Zigbee::ZigbeeProfileHomeAutomation) {
|
||||||
|
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::HomeAutomationDevice>(deviceId);
|
||||||
|
} else if (profileId == Zigbee::ZigbeeProfileGreenPower) {
|
||||||
|
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::GreenPowerDevice>(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << "Endpoints" << endpointCount;
|
qCDebug(dcZigbeeNode()) << " Device version:" << ZigbeeUtils::convertByteToHexString(deviceVersion);
|
||||||
for (int i = 0; i < m_uninitializedEndpoints.count(); i++) {
|
|
||||||
qCDebug(dcZigbeeNode()) << " -" << ZigbeeUtils::convertByteToHexString(m_uninitializedEndpoints.at(i));
|
// Create endpoint
|
||||||
|
ZigbeeNodeEndpointDeconz *endpoint = nullptr;
|
||||||
|
if (!hasEndpoint(endpointId)) {
|
||||||
|
ZigbeeNodeEndpointDeconz *endpoint = qobject_cast<ZigbeeNodeEndpointDeconz *>(createNodeEndpoint(endpointId, this));
|
||||||
|
m_endpoints.append(endpoint);
|
||||||
|
} else {
|
||||||
|
endpoint = qobject_cast<ZigbeeNodeEndpointDeconz *>(getEndpoint(endpointId));
|
||||||
|
}
|
||||||
|
endpoint->setProfile(static_cast<Zigbee::ZigbeeProfile>(profileId));
|
||||||
|
endpoint->setDeviceId(deviceId);
|
||||||
|
endpoint->setDeviceVersion(deviceVersion);
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNode()) << " Input clusters: (" << inputClusterCount << ")";
|
||||||
|
for (int i = 0; i < inputClusterCount; i++) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
||||||
|
|
||||||
|
}
|
||||||
|
stream >> outputClusterCount;
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNode()) << " Output clusters: (" << outputClusterCount << ")";
|
||||||
|
for (int i = 0; i < outputClusterCount; i++) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read simple descriptor for each endpoint
|
m_uninitializedEndpoints.removeAll(endpointId);
|
||||||
|
|
||||||
if (m_uninitializedEndpoints.isEmpty()) {
|
if (m_uninitializedEndpoints.isEmpty()) {
|
||||||
setState(StateInitialized);
|
// Continue with the basic cluster attributes
|
||||||
}
|
initBasicCluster();
|
||||||
|
|
||||||
for (int i = 0; i < m_uninitializedEndpoints.count(); i++) {
|
|
||||||
quint8 endpointId = m_uninitializedEndpoints.at(i);
|
|
||||||
qCDebug(dcZigbeeNode()) << "Read simple descriptor of endpoint" << ZigbeeUtils::convertByteToHexString(endpointId);
|
|
||||||
ZigbeeNetworkReply *reply = requestSimpleDescriptor(endpointId);
|
|
||||||
connect(reply, &ZigbeeNetworkReply::finished, this, [this, reply, endpointId](){
|
|
||||||
// TODO: check reply error
|
|
||||||
ZigbeeDeviceProfileAdpu adpu = ZigbeeDeviceProfile::parseAdpu(reply->responseData());
|
|
||||||
qCDebug(dcZigbeeNode()) << "Simple descriptor request finished" << this << endpointId << adpu;
|
|
||||||
|
|
||||||
QDataStream stream(adpu.payload);
|
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
|
||||||
quint8 length = 0;
|
|
||||||
quint8 endpoint = 0;
|
|
||||||
quint16 profileId = 0;
|
|
||||||
quint16 deviceId = 0;
|
|
||||||
quint8 deviceVersion = 0;
|
|
||||||
quint8 inputClusterCount = 0;
|
|
||||||
quint8 outputClusterCount = 0;
|
|
||||||
|
|
||||||
QList<quint16> inputClusters;
|
|
||||||
QList<quint16> outputClusters;
|
|
||||||
|
|
||||||
stream >> length >> endpoint >> profileId >> deviceId >> deviceVersion >> inputClusterCount;
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << "Node endpoint simple descriptor:";
|
|
||||||
qCDebug(dcZigbeeNode()) << " Lenght:" << ZigbeeUtils::convertByteToHexString(length);
|
|
||||||
qCDebug(dcZigbeeNode()) << " End Point:" << ZigbeeUtils::convertByteToHexString(endpoint);
|
|
||||||
qCDebug(dcZigbeeNode()) << " Profile:" << ZigbeeUtils::profileIdToString(static_cast<Zigbee::ZigbeeProfile>(profileId));
|
|
||||||
if (profileId == Zigbee::ZigbeeProfileLightLink) {
|
|
||||||
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::LightLinkDevice>(deviceId);
|
|
||||||
} else if (profileId == Zigbee::ZigbeeProfileHomeAutomation) {
|
|
||||||
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::HomeAutomationDevice>(deviceId);
|
|
||||||
} else if (profileId == Zigbee::ZigbeeProfileGreenPower) {
|
|
||||||
qCDebug(dcZigbeeNode()) << " Device ID:" << ZigbeeUtils::convertUint16ToHexString(deviceId) << static_cast<Zigbee::GreenPowerDevice>(deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << " Device version:" << ZigbeeUtils::convertByteToHexString(deviceVersion);
|
|
||||||
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << " Input clusters: (" << inputClusterCount << ")";
|
|
||||||
|
|
||||||
for (int i = 0; i < inputClusterCount; i++) {
|
|
||||||
quint16 clusterId = 0;
|
|
||||||
stream >> clusterId;
|
|
||||||
inputClusters.append(clusterId);
|
|
||||||
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
|
||||||
|
|
||||||
}
|
|
||||||
stream >> outputClusterCount;
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNode()) << " Output clusters: (" << outputClusterCount << ")";
|
|
||||||
for (int i = 0; i < outputClusterCount; i++) {
|
|
||||||
quint16 clusterId = 0;
|
|
||||||
stream >> clusterId;
|
|
||||||
outputClusters.append(clusterId);
|
|
||||||
qCDebug(dcZigbeeNode()) << " Cluster ID:" << ZigbeeUtils::convertUint16ToHexString(clusterId) << ZigbeeUtils::clusterIdToString(static_cast<Zigbee::ClusterId>(clusterId));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_uninitializedEndpoints.removeAll(endpointId);
|
|
||||||
|
|
||||||
// Create endpoint
|
|
||||||
|
|
||||||
|
|
||||||
if (m_uninitializedEndpoints.isEmpty()) {
|
|
||||||
setState(StateInitialized);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNodeDeconz::initBasicCluster()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setState(StateInitialized);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNodeDeconz::setClusterAttributeReport(const ZigbeeClusterAttributeReport &report)
|
||||||
|
{
|
||||||
|
Q_UNUSED(report)
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNodeDeconz::startInitialization()
|
||||||
|
{
|
||||||
|
setState(StateInitializing);
|
||||||
|
|
||||||
|
/* Node initialisation steps (sequentially)
|
||||||
|
* - Node descriptor
|
||||||
|
* - Power descriptor
|
||||||
|
* - Active endpoints
|
||||||
|
* - for each endpoint do:
|
||||||
|
* - Simple descriptor request
|
||||||
|
* - for each endpoint
|
||||||
|
* - read basic cluster
|
||||||
|
*/
|
||||||
|
|
||||||
|
initNodeDescriptor();
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeNodeEndpoint *ZigbeeNodeDeconz::createNodeEndpoint(quint8 endpointId, QObject *parent)
|
ZigbeeNodeEndpoint *ZigbeeNodeDeconz::createNodeEndpoint(quint8 endpointId, QObject *parent)
|
||||||
{
|
{
|
||||||
Q_UNUSED(endpointId)
|
return qobject_cast<ZigbeeNodeEndpoint *>(new ZigbeeNodeEndpointDeconz(m_network, this, endpointId, parent));
|
||||||
Q_UNUSED(parent)
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
#include "zigbeenode.h"
|
#include "zigbeenode.h"
|
||||||
|
|
||||||
|
class ZigbeeNodeEndpoint;
|
||||||
class ZigbeeNetworkDeconz;
|
class ZigbeeNetworkDeconz;
|
||||||
|
|
||||||
class ZigbeeNodeDeconz : public ZigbeeNode
|
class ZigbeeNodeDeconz : public ZigbeeNode
|
||||||
@ -54,6 +55,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
ZigbeeNetworkDeconz *m_network = nullptr;
|
ZigbeeNetworkDeconz *m_network = nullptr;
|
||||||
|
|
||||||
|
// Init methods
|
||||||
|
void initNodeDescriptor();
|
||||||
|
void initPowerDescriptor();
|
||||||
|
void initEndpoints();
|
||||||
|
void initBasicCluster();
|
||||||
|
|
||||||
QList<quint8> m_uninitializedEndpoints;
|
QList<quint8> m_uninitializedEndpoints;
|
||||||
QList<quint16> m_uninitalizedBasicClusterAttributes;
|
QList<quint16> m_uninitalizedBasicClusterAttributes;
|
||||||
|
|
||||||
|
|||||||
@ -26,8 +26,32 @@
|
|||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "zigbeenodeendpointdeconz.h"
|
#include "zigbeenodeendpointdeconz.h"
|
||||||
|
#include "zigbeenodeendpoint.h"
|
||||||
|
|
||||||
ZigbeeNodeEndpointDeconz::ZigbeeNodeEndpointDeconz(QObject *parent) : QObject(parent)
|
ZigbeeNodeEndpointDeconz::ZigbeeNodeEndpointDeconz(ZigbeeNetworkDeconz *network, ZigbeeNode *node, quint8 endpointId, QObject *parent) :
|
||||||
|
ZigbeeNodeEndpoint(node, endpointId, parent),
|
||||||
|
m_network(network),
|
||||||
|
m_node(node)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
Q_UNUSED(attribute)
|
||||||
|
}
|
||||||
|
|||||||
@ -29,12 +29,30 @@
|
|||||||
#define ZIGBEENODEENDPOINTDECONZ_H
|
#define ZIGBEENODEENDPOINTDECONZ_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include "zigbeenodeendpoint.h"
|
||||||
|
|
||||||
class ZigbeeNodeEndpointDeconz : public QObject
|
class ZigbeeNodeDeconz;
|
||||||
|
class ZigbeeNetworkDeconz;
|
||||||
|
|
||||||
|
class ZigbeeNodeEndpointDeconz : public ZigbeeNodeEndpoint
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend class ZigbeeNodeDeconz;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ZigbeeNodeEndpointDeconz(QObject *parent = nullptr);
|
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;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZigbeeNetworkDeconz *m_network = nullptr;
|
||||||
|
ZigbeeNode *m_node = nullptr;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ SOURCES += \
|
|||||||
zigbeechannelmask.cpp \
|
zigbeechannelmask.cpp \
|
||||||
zigbeecluster.cpp \
|
zigbeecluster.cpp \
|
||||||
zigbeeclusterattribute.cpp \
|
zigbeeclusterattribute.cpp \
|
||||||
|
zigbeeclusterlibrary.cpp \
|
||||||
zigbeedeviceprofile.cpp \
|
zigbeedeviceprofile.cpp \
|
||||||
zigbeemanufacturer.cpp \
|
zigbeemanufacturer.cpp \
|
||||||
zigbeenetwork.cpp \
|
zigbeenetwork.cpp \
|
||||||
@ -59,6 +60,7 @@ HEADERS += \
|
|||||||
zigbeechannelmask.h \
|
zigbeechannelmask.h \
|
||||||
zigbeecluster.h \
|
zigbeecluster.h \
|
||||||
zigbeeclusterattribute.h \
|
zigbeeclusterattribute.h \
|
||||||
|
zigbeeclusterlibrary.h \
|
||||||
zigbeedeviceprofile.h \
|
zigbeedeviceprofile.h \
|
||||||
zigbeemanufacturer.h \
|
zigbeemanufacturer.h \
|
||||||
zigbeenetwork.h \
|
zigbeenetwork.h \
|
||||||
|
|||||||
176
libnymea-zigbee/zigbeeclusterlibrary.cpp
Normal file
176
libnymea-zigbee/zigbeeclusterlibrary.cpp
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* 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 "zigbeeclusterlibrary.h"
|
||||||
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
quint8 ZigbeeClusterLibrary::buildFrameControlByte(const ZigbeeClusterLibrary::FrameControl &frameControl)
|
||||||
|
{
|
||||||
|
quint8 byte = 0x00;
|
||||||
|
|
||||||
|
// Bit 0-1
|
||||||
|
byte |= FrameTypeClusterSpecific;
|
||||||
|
|
||||||
|
// Bit 2
|
||||||
|
if (frameControl.manufacturerSpecific)
|
||||||
|
byte |= 0x01 << 2;
|
||||||
|
|
||||||
|
// Bit 3
|
||||||
|
if (frameControl.direction == DirectionServerToClient)
|
||||||
|
byte |= 0x01 << 3;
|
||||||
|
|
||||||
|
// Bit 4
|
||||||
|
if (frameControl.disableDefaultResponse)
|
||||||
|
byte |= 0x01 << 4;
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeClusterLibrary::FrameControl ZigbeeClusterLibrary::parseFrameControlByte(quint8 frameControlByte)
|
||||||
|
{
|
||||||
|
FrameControl frameControl;
|
||||||
|
|
||||||
|
if (ZigbeeUtils::checkBitUint8(frameControlByte, 0)) {
|
||||||
|
frameControl.frameType = FrameTypeClusterSpecific;
|
||||||
|
} else {
|
||||||
|
frameControl.frameType = FrameTypeGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
|
frameControl.manufacturerSpecific = ZigbeeUtils::checkBitUint8(frameControlByte, 2);
|
||||||
|
|
||||||
|
if (ZigbeeUtils::checkBitUint8(frameControlByte, 3)) {
|
||||||
|
frameControl.direction = DirectionServerToClient;
|
||||||
|
} else {
|
||||||
|
frameControl.direction = DirectionClientToServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
frameControl.disableDefaultResponse = ZigbeeUtils::checkBitUint8(frameControlByte, 4);
|
||||||
|
|
||||||
|
return frameControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ZigbeeClusterLibrary::buildHeader(const ZigbeeClusterLibrary::Header &header)
|
||||||
|
{
|
||||||
|
QByteArray headerData;
|
||||||
|
QDataStream stream(&headerData, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << buildFrameControlByte(header.frameControl);
|
||||||
|
|
||||||
|
// Include manufacturer only if the frame control indicates manufacturer specific
|
||||||
|
if (header.frameControl.manufacturerSpecific) {
|
||||||
|
stream << header.manufacturerCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << header.transactionSequenceNumber;
|
||||||
|
stream << static_cast<quint8>(header.command);
|
||||||
|
|
||||||
|
return headerData;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeClusterLibrary::Frame ZigbeeClusterLibrary::parseFrameData(const QByteArray &frameData)
|
||||||
|
{
|
||||||
|
QDataStream stream(frameData);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
// Read the header and then the payload
|
||||||
|
quint8 offset = 0;
|
||||||
|
quint8 frameControlByte = 0;
|
||||||
|
quint8 commandByte = 0;
|
||||||
|
|
||||||
|
Header header;
|
||||||
|
stream >> frameControlByte;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
header.frameControl = parseFrameControlByte(frameControlByte);
|
||||||
|
if (header.frameControl.manufacturerSpecific) {
|
||||||
|
stream >> header.manufacturerCode;
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream >> header.transactionSequenceNumber;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
|
||||||
|
stream >> commandByte;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
header.command = static_cast<Command>(commandByte);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
Frame frame;
|
||||||
|
frame.header = header;
|
||||||
|
frame.payload = frameData.right(frameData.length() - offset);
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ZigbeeClusterLibrary::buildFrame(const ZigbeeClusterLibrary::Frame &frame)
|
||||||
|
{
|
||||||
|
return buildHeader(frame.header) + frame.payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::FrameControl &frameControl)
|
||||||
|
{
|
||||||
|
debug.nospace() << "FrameControl(";
|
||||||
|
if (frameControl.frameType == ZigbeeClusterLibrary::FrameTypeGlobal) {
|
||||||
|
debug.nospace() << "Frame Type: Global" << ", ";
|
||||||
|
} else {
|
||||||
|
debug.nospace() << "Frame Type: Cluster specific" << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.nospace() << "Manufacturer specific: " << (frameControl.manufacturerSpecific ? "1" : "0") << ", ";
|
||||||
|
debug.nospace() << "Direction: ";
|
||||||
|
if (frameControl.direction == ZigbeeClusterLibrary::DirectionClientToServer) {
|
||||||
|
debug.nospace() << "Client to server, ";
|
||||||
|
} else {
|
||||||
|
debug.nospace() << "Server to client, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.nospace() << "Disable default response: " << (frameControl.disableDefaultResponse ? "1" : "0") << ")";
|
||||||
|
return debug.space();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Header &header)
|
||||||
|
{
|
||||||
|
debug.nospace() << "Header(";
|
||||||
|
debug.nospace() << header.frameControl;
|
||||||
|
if (header.frameControl.manufacturerSpecific) {
|
||||||
|
debug.nospace() << "Manufacturer code: " << ZigbeeUtils::convertUint16ToHexString(header.manufacturerCode) << ", ";
|
||||||
|
}
|
||||||
|
debug.nospace() << "TSN:" << header.transactionSequenceNumber << ", ";
|
||||||
|
debug.nospace() << header.command << ")";
|
||||||
|
return debug.space();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Frame &frame)
|
||||||
|
{
|
||||||
|
debug.nospace() << "Zigbee Cluster Library Frame(";
|
||||||
|
debug.nospace() << frame.header;
|
||||||
|
debug.nospace() << ZigbeeUtils::convertByteArrayToHexString(frame.payload) << ")";
|
||||||
|
return debug.space();
|
||||||
|
}
|
||||||
112
libnymea-zigbee/zigbeeclusterlibrary.h
Normal file
112
libnymea-zigbee/zigbeeclusterlibrary.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* 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 ZIGBEECLUSTERLIBRARY_H
|
||||||
|
#define ZIGBEECLUSTERLIBRARY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class ZigbeeClusterLibrary
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
public:
|
||||||
|
enum Command {
|
||||||
|
CommandReadAttributes = 0x00,
|
||||||
|
CommandReadAttributesResponse = 0x01,
|
||||||
|
CommandWriteAttributes = 0x02,
|
||||||
|
CommandWriteAttributesUndivided = 0x03,
|
||||||
|
CommandWriteAttributesResponse = 0x04,
|
||||||
|
CommandWriteAttributesNoResponse = 0x05,
|
||||||
|
CommandConfigureReporting = 0x06,
|
||||||
|
CommandConfigureReportingResponse = 0x07,
|
||||||
|
CommandReadReportingConfiguration = 0x08,
|
||||||
|
CommandReadReportingConfigurationResponse = 0x09,
|
||||||
|
CommandReportAttributes = 0x0a,
|
||||||
|
CommandDefaultResponse = 0x0b,
|
||||||
|
CommandDiscoverAttributes = 0x0c,
|
||||||
|
CommandDiscoverAttributesResponse = 0x0d,
|
||||||
|
CommandReadAttributesStructured = 0x0e,
|
||||||
|
CommandWriteAttributesStructured = 0x0f,
|
||||||
|
CommandWriteAttributesStructuredResponse = 0x10,
|
||||||
|
CommandDiscoverCommandsReceived = 0x11,
|
||||||
|
CommandDiscoverCommandsReceivedResponse = 0x12,
|
||||||
|
CommandDiscoverCommandsGenerated = 0x13,
|
||||||
|
CommandDiscoverCommandsGeneratedResponse = 0x14,
|
||||||
|
CommandDiscoverAttributesExtended = 0x15,
|
||||||
|
CommandDiscoverAttributesExtendedResponse = 0x16
|
||||||
|
};
|
||||||
|
Q_ENUM(Command)
|
||||||
|
|
||||||
|
// Frame control field
|
||||||
|
enum FrameType {
|
||||||
|
FrameTypeGlobal = 0x00,
|
||||||
|
FrameTypeClusterSpecific = 0x01
|
||||||
|
};
|
||||||
|
Q_ENUM(FrameType)
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
DirectionClientToServer = 0x00,
|
||||||
|
DirectionServerToClient = 0x01
|
||||||
|
};
|
||||||
|
Q_ENUM(Direction)
|
||||||
|
|
||||||
|
typedef struct FrameControl {
|
||||||
|
FrameType frameType = FrameTypeClusterSpecific;
|
||||||
|
bool manufacturerSpecific = false;
|
||||||
|
Direction direction = DirectionClientToServer;
|
||||||
|
bool disableDefaultResponse = false;
|
||||||
|
} FrameControl;
|
||||||
|
|
||||||
|
typedef struct Header {
|
||||||
|
FrameControl frameControl;
|
||||||
|
quint16 manufacturerCode = 0;
|
||||||
|
quint8 transactionSequenceNumber = 0;
|
||||||
|
Command command;
|
||||||
|
} ZclHeader;
|
||||||
|
|
||||||
|
typedef struct Frame {
|
||||||
|
Header header;
|
||||||
|
QByteArray payload;
|
||||||
|
} Frame;
|
||||||
|
|
||||||
|
// General parse/build methods
|
||||||
|
static quint8 buildFrameControlByte(const FrameControl &frameControl);
|
||||||
|
static FrameControl parseFrameControlByte(quint8 frameControlByte);
|
||||||
|
|
||||||
|
static QByteArray buildHeader(const Header &header);
|
||||||
|
|
||||||
|
static Frame parseFrameData(const QByteArray &frameData);
|
||||||
|
static QByteArray buildFrame(const Frame &frame);
|
||||||
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::FrameControl &frameControl);
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Header &header);
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Frame &frame);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ZIGBEECLUSTERLIBRARY_H
|
||||||
@ -78,30 +78,30 @@ public:
|
|||||||
virtual ZigbeeNetworkReply *configureReporting(ZigbeeCluster *cluster, QList<ZigbeeClusterReportConfigurationRecord> reportConfigurations) = 0;
|
virtual ZigbeeNetworkReply *configureReporting(ZigbeeCluster *cluster, QList<ZigbeeClusterReportConfigurationRecord> reportConfigurations) = 0;
|
||||||
|
|
||||||
// Identify
|
// Identify
|
||||||
virtual ZigbeeNetworkReply *identify(quint16 seconds) = 0;
|
virtual ZigbeeNetworkReply *identify(quint16 seconds);
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
virtual ZigbeeNetworkReply *factoryReset() = 0;
|
virtual ZigbeeNetworkReply *factoryReset();
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
virtual ZigbeeNetworkReply *bindGroup(Zigbee::ClusterId clusterId, quint16 destinationAddress, quint8 destinationEndpoint) = 0;
|
virtual ZigbeeNetworkReply *bindGroup(Zigbee::ClusterId clusterId, quint16 destinationAddress, quint8 destinationEndpoint);
|
||||||
virtual ZigbeeNetworkReply *bindUnicast(Zigbee::ClusterId clusterId, const ZigbeeAddress &destinationAddress, quint8 destinationEndpoint) = 0;
|
virtual ZigbeeNetworkReply *bindUnicast(Zigbee::ClusterId clusterId, const ZigbeeAddress &destinationAddress, quint8 destinationEndpoint);
|
||||||
|
|
||||||
// Cluster commands
|
// Cluster commands
|
||||||
virtual ZigbeeNetworkReply *sendOnOffClusterCommand(ZigbeeCluster::OnOffClusterCommand command) = 0;
|
virtual ZigbeeNetworkReply *sendOnOffClusterCommand(ZigbeeCluster::OnOffClusterCommand command);
|
||||||
|
|
||||||
// Group commands
|
// Group commands
|
||||||
virtual ZigbeeNetworkReply *addGroup(quint8 destinationEndpoint, quint16 groupAddress) = 0;
|
virtual ZigbeeNetworkReply *addGroup(quint8 destinationEndpoint, quint16 groupAddress);
|
||||||
|
|
||||||
// Level commands
|
// Level commands
|
||||||
virtual ZigbeeNetworkReply *sendLevelCommand(ZigbeeCluster::LevelClusterCommand command, quint8 level, bool triggersOnOff, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendLevelCommand(ZigbeeCluster::LevelClusterCommand command, quint8 level, bool triggersOnOff, quint16 transitionTime);
|
||||||
|
|
||||||
// Color commands
|
// Color commands
|
||||||
virtual ZigbeeNetworkReply *sendMoveToColorTemperature(quint16 colourTemperature, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendMoveToColorTemperature(quint16 colourTemperature, quint16 transitionTime);
|
||||||
virtual ZigbeeNetworkReply *sendMoveToColor(double x, double y, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendMoveToColor(double x, double y, quint16 transitionTime);
|
||||||
virtual ZigbeeNetworkReply *sendMoveToHueSaturation(quint8 hue, quint8 saturation, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendMoveToHueSaturation(quint8 hue, quint8 saturation, quint16 transitionTime);
|
||||||
virtual ZigbeeNetworkReply *sendMoveToHue(quint8 hue, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendMoveToHue(quint8 hue, quint16 transitionTime);
|
||||||
virtual ZigbeeNetworkReply *sendMoveToSaturation(quint8 saturation, quint16 transitionTime) = 0;
|
virtual ZigbeeNetworkReply *sendMoveToSaturation(quint8 saturation, quint16 transitionTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeNode *m_node = nullptr;
|
ZigbeeNode *m_node = nullptr;
|
||||||
|
|||||||
@ -38,15 +38,6 @@
|
|||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
#include "zigbeecluster.h"
|
#include "zigbeecluster.h"
|
||||||
|
|
||||||
template<class TYPE> inline TYPE ZigbeeBit(const TYPE & x)
|
|
||||||
{
|
|
||||||
return TYPE(1) << x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TYPE> inline bool ZigbeeIsBitSet(const TYPE & x, const TYPE & y)
|
|
||||||
{
|
|
||||||
return (x & y) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ZigbeeUtils
|
class ZigbeeUtils
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user