Make udev optional and provide basic cluster information in node object
This commit is contained in:
parent
72150b6bfb
commit
3997b5a5de
@ -415,7 +415,6 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
||||
setChannel(channel);
|
||||
|
||||
// Initialize the coordinator node if not already done.
|
||||
|
||||
if (m_coordinatorNode) {
|
||||
if (!macAddress().isNull() && ZigbeeAddress(ieeeAddress) != macAddress()) {
|
||||
qCWarning(dcZigbeeNetwork()) << "The mac address of the coordinator has changed since the network has been set up.";
|
||||
@ -427,6 +426,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
|
||||
setNodeInformation(m_coordinatorNode, "NXP", "JN516x", bridgeController()->firmwareVersion());
|
||||
m_database->saveNode(m_coordinatorNode);
|
||||
setPermitJoining(0);
|
||||
setState(StateRunning);
|
||||
@ -440,6 +440,7 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
||||
connect(coordinatorNode, &ZigbeeNode::stateChanged, this, [this, coordinatorNode](ZigbeeNode::State state){
|
||||
if (state == ZigbeeNode::StateInitialized) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
||||
setNodeInformation(m_coordinatorNode, "NXP", "JN516x", bridgeController()->firmwareVersion());
|
||||
/* Note: this currently has been hardcoded into the firmware. TODO: implement appropriate method for binding coordinator to group
|
||||
|
||||
ZigbeeClusterGroups *groupsCluster = coordinatorNode->getEndpoint(0x01)->inputCluster<ZigbeeClusterGroups>(ZigbeeClusterLibrary::ClusterIdGroups);
|
||||
|
||||
@ -3,8 +3,14 @@ include(../config.pri)
|
||||
TARGET = nymea-zigbee1
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += libudev
|
||||
|
||||
disable_udev {
|
||||
message(Build without libudev support)
|
||||
DEFINES += DISABLE_UDEV
|
||||
} else {
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += libudev
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
backends/deconz/interface/zigbeeinterfacedeconz.cpp \
|
||||
|
||||
@ -541,6 +541,7 @@ void ZigbeeNetwork::addUnitializedNode(ZigbeeNode *node)
|
||||
});
|
||||
|
||||
m_uninitializedNodes.append(node);
|
||||
emit nodeJoined(node);
|
||||
}
|
||||
|
||||
void ZigbeeNetwork::removeNode(ZigbeeNode *node)
|
||||
@ -562,6 +563,18 @@ void ZigbeeNetwork::setNodeReachable(ZigbeeNode *node, bool reachable)
|
||||
node->setReachable(reachable);
|
||||
}
|
||||
|
||||
void ZigbeeNetwork::setNodeInformation(ZigbeeNode *node, const QString &manufacturerName, const QString &modelName, const QString &version)
|
||||
{
|
||||
node->m_manufacturerName = manufacturerName;
|
||||
emit node->manufacturerNameChanged(node->manufacturerName());
|
||||
|
||||
node->m_modelName = modelName;
|
||||
emit node->modelNameChanged(node->modelName());
|
||||
|
||||
node->m_version = version;
|
||||
emit node->versionChanged(node->version());
|
||||
}
|
||||
|
||||
void ZigbeeNetwork::setState(ZigbeeNetwork::State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
|
||||
@ -192,6 +192,9 @@ protected:
|
||||
|
||||
void setNodeReachable(ZigbeeNode *node, bool reachable);
|
||||
|
||||
// Set the coordinator infromation since they cannot be fetched
|
||||
void setNodeInformation(ZigbeeNode *node, const QString &manufacturerName, const QString &modelName, const QString &version);
|
||||
|
||||
void setState(State state);
|
||||
void setError(Error error);
|
||||
|
||||
@ -218,9 +221,13 @@ signals:
|
||||
void channelMaskChanged(const ZigbeeChannelMask &channelMask);
|
||||
void securityConfigurationChanged(const ZigbeeSecurityConfiguration &securityConfiguration);
|
||||
|
||||
// Will be emitted if node has joined and the initialization has been finished
|
||||
void nodeAdded(ZigbeeNode *node);
|
||||
void nodeRemoved(ZigbeeNode *node);
|
||||
|
||||
// Will be emited when a node joined and starts initializing
|
||||
void nodeJoined(ZigbeeNode *node);
|
||||
|
||||
void permitJoiningEnabledChanged(bool permitJoiningEnabled);
|
||||
void permitJoinDurationChanged(quint8 duration);
|
||||
void permitJoinRemainingChanged(quint8 remaining);
|
||||
|
||||
@ -139,19 +139,24 @@ QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes()
|
||||
}
|
||||
}
|
||||
|
||||
// Set the basic cluster attributes if present
|
||||
// Set the basic cluster attributes if present to endpoint and node
|
||||
if (endpoint->hasInputCluster(ZigbeeClusterLibrary::ClusterIdBasic)) {
|
||||
ZigbeeClusterBasic *basicCluster = endpoint->inputCluster<ZigbeeClusterBasic>(ZigbeeClusterLibrary::ClusterIdBasic);
|
||||
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeManufacturerName))
|
||||
endpoint->m_manufacturerName = basicCluster->attribute(ZigbeeClusterBasic::AttributeManufacturerName).dataType().toString();
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeManufacturerName)) {
|
||||
endpoint->setManufacturerName(basicCluster->attribute(ZigbeeClusterBasic::AttributeManufacturerName).dataType().toString());
|
||||
node->m_manufacturerName = endpoint->manufacturerName();
|
||||
}
|
||||
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeModelIdentifier))
|
||||
endpoint->m_modelIdentifier = basicCluster->attribute(ZigbeeClusterBasic::AttributeModelIdentifier).dataType().toString();
|
||||
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeSwBuildId))
|
||||
endpoint->m_softwareBuildId = basicCluster->attribute(ZigbeeClusterBasic::AttributeSwBuildId).dataType().toString();
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeModelIdentifier)) {
|
||||
endpoint->setModelIdentifier(basicCluster->attribute(ZigbeeClusterBasic::AttributeModelIdentifier).dataType().toString());
|
||||
node->m_modelName = endpoint->modelIdentifier();
|
||||
}
|
||||
|
||||
if (basicCluster->hasAttribute(ZigbeeClusterBasic::AttributeSwBuildId)) {
|
||||
endpoint->setSoftwareBuildId(basicCluster->attribute(ZigbeeClusterBasic::AttributeSwBuildId).dataType().toString());
|
||||
node->m_version = endpoint->softwareBuildId();
|
||||
}
|
||||
}
|
||||
|
||||
// Load output clusters for this endpoint
|
||||
|
||||
@ -92,6 +92,21 @@ ZigbeeNodeEndpoint *ZigbeeNode::getEndpoint(quint8 endpointId) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString ZigbeeNode::manufacturerName() const
|
||||
{
|
||||
return m_manufacturerName;
|
||||
}
|
||||
|
||||
QString ZigbeeNode::modelName() const
|
||||
{
|
||||
return m_modelName;
|
||||
}
|
||||
|
||||
QString ZigbeeNode::version() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
quint8 ZigbeeNode::lqi() const
|
||||
{
|
||||
return m_lqi;
|
||||
@ -522,6 +537,8 @@ void ZigbeeNode::readManufacturerName(ZigbeeClusterBasic *basicCluster)
|
||||
QString manufacturerName = basicCluster->attribute(attributeId).dataType().toString(&valueOk);
|
||||
if (valueOk) {
|
||||
endpoints().first()->m_manufacturerName = manufacturerName;
|
||||
m_manufacturerName = manufacturerName;
|
||||
emit manufacturerNameChanged(m_manufacturerName);
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Could not convert manufacturer name attribute data to string" << basicCluster->attribute(attributeId).dataType();
|
||||
}
|
||||
@ -557,6 +574,8 @@ void ZigbeeNode::readManufacturerName(ZigbeeClusterBasic *basicCluster)
|
||||
QString manufacturerName = attributeStatusRecord.dataType.toString(&valueOk);
|
||||
if (valueOk) {
|
||||
endpoints().first()->m_manufacturerName = manufacturerName;
|
||||
m_manufacturerName = manufacturerName;
|
||||
emit manufacturerNameChanged(m_manufacturerName);
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Could not convert manufacturer name attribute data to string" << attributeStatusRecord.dataType;
|
||||
}
|
||||
@ -581,6 +600,8 @@ void ZigbeeNode::readModelIdentifier(ZigbeeClusterBasic *basicCluster)
|
||||
QString modelIdentifier = basicCluster->attribute(attributeId).dataType().toString(&valueOk);
|
||||
if (valueOk) {
|
||||
endpoints().first()->m_modelIdentifier= modelIdentifier;
|
||||
m_modelName = modelIdentifier;
|
||||
emit modelNameChanged(m_modelName);
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Could not convert model identifier attribute data to string" << basicCluster->attribute(attributeId).dataType();
|
||||
}
|
||||
@ -616,6 +637,8 @@ void ZigbeeNode::readModelIdentifier(ZigbeeClusterBasic *basicCluster)
|
||||
QString modelIdentifier = attributeStatusRecord.dataType.toString(&valueOk);
|
||||
if (valueOk) {
|
||||
endpoints().first()->m_modelIdentifier = modelIdentifier;
|
||||
m_modelName = modelIdentifier;
|
||||
emit modelNameChanged(m_modelName);
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Could not convert model identifier attribute data to string" << attributeStatusRecord.dataType;
|
||||
}
|
||||
@ -657,6 +680,8 @@ void ZigbeeNode::readSoftwareBuildId(ZigbeeClusterBasic *basicCluster)
|
||||
QString softwareBuildId = attributeStatusRecord.dataType.toString(&valueOk);
|
||||
if (valueOk) {
|
||||
endpoints().first()->m_softwareBuildId = softwareBuildId;
|
||||
m_version = softwareBuildId;
|
||||
emit versionChanged(m_version);
|
||||
} else {
|
||||
qCWarning(dcZigbeeNode()) << "Could not convert software build id attribute data to string" << attributeStatusRecord.dataType;
|
||||
}
|
||||
|
||||
@ -72,6 +72,11 @@ public:
|
||||
bool hasEndpoint(quint8 endpointId) const;
|
||||
ZigbeeNodeEndpoint *getEndpoint(quint8 endpointId) const;
|
||||
|
||||
// Basic cluster infomation
|
||||
QString manufacturerName() const;
|
||||
QString modelName() const;
|
||||
QString version() const;
|
||||
|
||||
quint8 lqi() const;
|
||||
QDateTime lastSeen() const;
|
||||
|
||||
@ -102,6 +107,11 @@ private:
|
||||
quint16 m_shortAddress = 0;
|
||||
ZigbeeAddress m_extendedAddress;
|
||||
|
||||
// Basic cluster infomation
|
||||
QString m_manufacturerName;
|
||||
QString m_modelName;
|
||||
QString m_version;
|
||||
|
||||
ZigbeeDeviceObject *m_deviceObject = nullptr;
|
||||
QList<ZigbeeNodeEndpoint *> m_endpoints;
|
||||
bool m_reachable = false;
|
||||
@ -144,6 +154,9 @@ signals:
|
||||
void stateChanged(State state);
|
||||
void lqiChanged(quint8 lqi);
|
||||
void lastSeenChanged(const QDateTime &lastSeen);
|
||||
void manufacturerNameChanged(const QString &manufacturerName);
|
||||
void modelNameChanged(const QString &modelName);
|
||||
void versionChanged(const QString &version);
|
||||
void reachableChanged(bool reachable);
|
||||
void bindingTableRecordsChanged();
|
||||
void clusterAdded(ZigbeeCluster *cluster);
|
||||
|
||||
@ -30,23 +30,49 @@
|
||||
|
||||
#include <QSerialPortInfo>
|
||||
|
||||
#ifndef DISABLE_UDEV
|
||||
#include <libudev.h>
|
||||
#endif
|
||||
|
||||
ZigbeeUartAdapterMonitor::ZigbeeUartAdapterMonitor(QObject *parent) : QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<ZigbeeUartAdapter>();
|
||||
|
||||
// Read initially all tty devices
|
||||
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
|
||||
addAdapterInternally(serialPortInfo.systemLocation());
|
||||
}
|
||||
|
||||
#ifdef DISABLE_UDEV
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setInterval(5000);
|
||||
m_timer->setSingleShot(false);
|
||||
connect(m_timer, &QTimer::timeout, this, [=](){
|
||||
QStringList availablePorts;
|
||||
// Add a new adapter if not in the list already
|
||||
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
|
||||
availablePorts.append(serialPortInfo.systemLocation());
|
||||
if (!m_availableAdapters.contains(serialPortInfo.systemLocation())) {
|
||||
addAdapterInternally(serialPortInfo.systemLocation());
|
||||
}
|
||||
}
|
||||
// Remove adapters no longer available
|
||||
foreach (const QString &systemLocation, m_availableAdapters.keys()) {
|
||||
if (!availablePorts.contains(systemLocation)) {
|
||||
emit adapterRemoved(m_availableAdapters.take(systemLocation));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
#else
|
||||
// Init udev
|
||||
m_udev = udev_new();
|
||||
if (!m_udev) {
|
||||
qCWarning(dcZigbeeAdapterMonitor()) << "Could not initialize udev for the adapter monitor";
|
||||
return;
|
||||
}
|
||||
|
||||
// Read initially all tty devices
|
||||
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
|
||||
addAdapterInternally(serialPortInfo.systemLocation());
|
||||
}
|
||||
|
||||
// Create udev monitor
|
||||
m_monitor = udev_monitor_new_from_netlink(m_udev, "udev");
|
||||
if (!m_monitor) {
|
||||
@ -124,11 +150,15 @@ ZigbeeUartAdapterMonitor::ZigbeeUartAdapterMonitor(QObject *parent) : QObject(pa
|
||||
});
|
||||
|
||||
m_notifier->setEnabled(true);
|
||||
#endif
|
||||
|
||||
m_isValid = true;
|
||||
}
|
||||
|
||||
ZigbeeUartAdapterMonitor::~ZigbeeUartAdapterMonitor()
|
||||
{
|
||||
#ifndef DISABLE_UDEV
|
||||
|
||||
if (m_notifier)
|
||||
delete m_notifier;
|
||||
|
||||
@ -137,7 +167,7 @@ ZigbeeUartAdapterMonitor::~ZigbeeUartAdapterMonitor()
|
||||
|
||||
if (m_udev)
|
||||
udev_unref(m_udev);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
QList<ZigbeeUartAdapter> ZigbeeUartAdapterMonitor::availableAdapters() const
|
||||
|
||||
@ -31,6 +31,10 @@
|
||||
#include <QObject>
|
||||
#include <QSocketNotifier>
|
||||
|
||||
#ifdef DISABLE_UDEV
|
||||
#include <QTimer>
|
||||
#endif
|
||||
|
||||
#include "zigbeeuartadapter.h"
|
||||
|
||||
class ZigbeeUartAdapterMonitor : public QObject
|
||||
@ -47,9 +51,14 @@ public:
|
||||
|
||||
private:
|
||||
bool m_isValid = false;
|
||||
|
||||
#ifdef DISABLE_UDEV
|
||||
QTimer *m_timer = nullptr;
|
||||
#else
|
||||
struct udev *m_udev = nullptr;
|
||||
struct udev_monitor *m_monitor = nullptr;
|
||||
QSocketNotifier *m_notifier = nullptr;
|
||||
#endif
|
||||
|
||||
QHash<QString, ZigbeeUartAdapter> m_availableAdapters;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user