Add zigbee uart monitor
This commit is contained in:
parent
5e2426165c
commit
097254756e
18
debian/control
vendored
18
debian/control
vendored
@ -7,12 +7,13 @@ Homepage: https://nymea.io
|
|||||||
Vcs-Git: https://github.com/nymea/nymea-zigbee.git
|
Vcs-Git: https://github.com/nymea/nymea-zigbee.git
|
||||||
Build-Depends: debhelper (>= 9.0.0),
|
Build-Depends: debhelper (>= 9.0.0),
|
||||||
dpkg-dev (>= 1.16.1~),
|
dpkg-dev (>= 1.16.1~),
|
||||||
|
pkg-config,
|
||||||
qt5-default,
|
qt5-default,
|
||||||
qt5-qmake,
|
qt5-qmake,
|
||||||
qtbase5-dev,
|
qtbase5-dev,
|
||||||
qtbase5-dev-tools,
|
qtbase5-dev-tools,
|
||||||
libqt5serialport5-dev,
|
libqt5serialport5-dev,
|
||||||
libreadline-dev
|
libudev-dev
|
||||||
|
|
||||||
Package: libnymea-zigbee1
|
Package: libnymea-zigbee1
|
||||||
Section: libs
|
Section: libs
|
||||||
@ -22,8 +23,8 @@ Depends: ${shlibs:Depends},
|
|||||||
libqt5network5,
|
libqt5network5,
|
||||||
libqt5gui5,
|
libqt5gui5,
|
||||||
libqt5serialport5
|
libqt5serialport5
|
||||||
Description: Qt 5 based library for Zigbee
|
Description: Qt 5 based library for ZigBee
|
||||||
Qt 5 based library for Zigbee.
|
Qt 5 based library for ZigBee.
|
||||||
|
|
||||||
|
|
||||||
Package: libnymea-zigbee-dev
|
Package: libnymea-zigbee-dev
|
||||||
@ -31,9 +32,10 @@ Section: libdevel
|
|||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: libnymea-zigbee1 (= ${binary:Version}),
|
Depends: libnymea-zigbee1 (= ${binary:Version}),
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
${misc:Depends}
|
${misc:Depends},
|
||||||
Description: Qt 5 based library for Zigbee - development files
|
pkg-config
|
||||||
Development files for Qt 5 based Zigbee library.
|
Dscription: Qt 5 based library for ZigBee - development files
|
||||||
|
Development files for Qt 5 based ZigBee library.
|
||||||
|
|
||||||
|
|
||||||
Package: libnymea-zigbee1-dbg
|
Package: libnymea-zigbee1-dbg
|
||||||
@ -43,5 +45,5 @@ Section: debug
|
|||||||
Depends: libnymea-zigbee1 (= ${binary:Version}),
|
Depends: libnymea-zigbee1 (= ${binary:Version}),
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
${misc:Depends}
|
${misc:Depends}
|
||||||
Description: Qt 5 based library for Zigbee - debug symbols
|
Description: Qt 5 based library for ZigBee - debug symbols
|
||||||
Debug Symbols for Qt 5 based Zigbee library.
|
Debug Symbols for Qt 5 based ZigBee library.
|
||||||
|
|||||||
@ -3,6 +3,9 @@ include(../config.pri)
|
|||||||
TARGET = nymea-zigbee1
|
TARGET = nymea-zigbee1
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
PKGCONFIG += libudev
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
backends/deconz/interface/zigbeeinterfacedeconz.cpp \
|
backends/deconz/interface/zigbeeinterfacedeconz.cpp \
|
||||||
backends/deconz/interface/zigbeeinterfacedeconzreply.cpp \
|
backends/deconz/interface/zigbeeinterfacedeconzreply.cpp \
|
||||||
@ -31,7 +34,6 @@ SOURCES += \
|
|||||||
zdo/zigbeedeviceobject.cpp \
|
zdo/zigbeedeviceobject.cpp \
|
||||||
zdo/zigbeedeviceobjectreply.cpp \
|
zdo/zigbeedeviceobjectreply.cpp \
|
||||||
zdo/zigbeedeviceprofile.cpp \
|
zdo/zigbeedeviceprofile.cpp \
|
||||||
zigbeeadapter.cpp \
|
|
||||||
zigbeeadpu.cpp \
|
zigbeeadpu.cpp \
|
||||||
zigbeebridgecontroller.cpp \
|
zigbeebridgecontroller.cpp \
|
||||||
zigbeechannelmask.cpp \
|
zigbeechannelmask.cpp \
|
||||||
@ -47,17 +49,11 @@ SOURCES += \
|
|||||||
zigbeenetworkrequest.cpp \
|
zigbeenetworkrequest.cpp \
|
||||||
zigbeenodeendpoint.cpp \
|
zigbeenodeendpoint.cpp \
|
||||||
zigbeesecurityconfiguration.cpp \
|
zigbeesecurityconfiguration.cpp \
|
||||||
|
zigbeeuartadapter.cpp \
|
||||||
|
zigbeeuartadaptermonitor.cpp \
|
||||||
zigbeeutils.cpp \
|
zigbeeutils.cpp \
|
||||||
zigbeenode.cpp \
|
zigbeenode.cpp \
|
||||||
zigbeeaddress.cpp \
|
zigbeeaddress.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 \
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
backends/deconz/interface/deconz.h \
|
backends/deconz/interface/deconz.h \
|
||||||
@ -89,7 +85,6 @@ HEADERS += \
|
|||||||
zdo/zigbeedeviceobject.h \
|
zdo/zigbeedeviceobject.h \
|
||||||
zdo/zigbeedeviceobjectreply.h \
|
zdo/zigbeedeviceobjectreply.h \
|
||||||
zdo/zigbeedeviceprofile.h \
|
zdo/zigbeedeviceprofile.h \
|
||||||
zigbeeadapter.h \
|
|
||||||
zigbeeadpu.h \
|
zigbeeadpu.h \
|
||||||
zigbeebridgecontroller.h \
|
zigbeebridgecontroller.h \
|
||||||
zigbeechannelmask.h \
|
zigbeechannelmask.h \
|
||||||
@ -105,17 +100,11 @@ HEADERS += \
|
|||||||
zigbeenetworkrequest.h \
|
zigbeenetworkrequest.h \
|
||||||
zigbeenodeendpoint.h \
|
zigbeenodeendpoint.h \
|
||||||
zigbeesecurityconfiguration.h \
|
zigbeesecurityconfiguration.h \
|
||||||
|
zigbeeuartadapter.h \
|
||||||
|
zigbeeuartadaptermonitor.h \
|
||||||
zigbeeutils.h \
|
zigbeeutils.h \
|
||||||
zigbeenode.h \
|
zigbeenode.h \
|
||||||
zigbeeaddress.h \
|
zigbeeaddress.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 \
|
|
||||||
|
|
||||||
# install header file with relative subdirectory
|
# install header file with relative subdirectory
|
||||||
for (header, HEADERS) {
|
for (header, HEADERS) {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ Q_LOGGING_CATEGORY(dcZigbeeEndpoint, "ZigbeeEndpoint")
|
|||||||
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
|
Q_LOGGING_CATEGORY(dcZigbeeInterface, "ZigbeeInterface")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
|
Q_LOGGING_CATEGORY(dcZigbeeController, "ZigbeeController")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeDeviceObject, "ZigbeeDeviceObject")
|
Q_LOGGING_CATEGORY(dcZigbeeDeviceObject, "ZigbeeDeviceObject")
|
||||||
|
Q_LOGGING_CATEGORY(dcZigbeeAdapterMonitor, "ZigbeeAdapterMonitor")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeClusterLibrary, "ZigbeeClusterLibrary")
|
Q_LOGGING_CATEGORY(dcZigbeeClusterLibrary, "ZigbeeClusterLibrary")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeNetworkDatabase, "ZigbeeNetworkDatabase")
|
Q_LOGGING_CATEGORY(dcZigbeeNetworkDatabase, "ZigbeeNetworkDatabase")
|
||||||
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")
|
Q_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic, "ZigbeeInterfaceTraffic")
|
||||||
|
|||||||
@ -39,6 +39,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcZigbeeEndpoint)
|
|||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterface)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeController)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeDeviceObject)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeDeviceObject)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeAdapterMonitor)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeClusterLibrary)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeClusterLibrary)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNetworkDatabase)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeNetworkDatabase)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)
|
Q_DECLARE_LOGGING_CATEGORY(dcZigbeeInterfaceTraffic)
|
||||||
|
|||||||
@ -32,58 +32,6 @@
|
|||||||
#include "backends/deconz/zigbeenetworkdeconz.h"
|
#include "backends/deconz/zigbeenetworkdeconz.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QSerialPortInfo>
|
|
||||||
|
|
||||||
QList<ZigbeeAdapter> ZigbeeNetworkManager::availableAdapters()
|
|
||||||
{
|
|
||||||
QList<ZigbeeAdapter> adapters;
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Loading available adapters" ;
|
|
||||||
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Adapter candidate" << serialPortInfo.portName();
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " Description:" << serialPortInfo.description();
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " System location:" << serialPortInfo.systemLocation();
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " Manufacturer:" << serialPortInfo.manufacturer();
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " Serialnumber:" << serialPortInfo.serialNumber();
|
|
||||||
|
|
||||||
if (serialPortInfo.hasProductIdentifier()) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " Product identifier:" << serialPortInfo.productIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serialPortInfo.hasVendorIdentifier()) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << " Vendor identifier:" << serialPortInfo.vendorIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we recognize this controller
|
|
||||||
ZigbeeAdapter adapter;
|
|
||||||
if (serialPortInfo.portName().isEmpty()) {
|
|
||||||
adapter.setName("Zigbee adapter");
|
|
||||||
} else {
|
|
||||||
adapter.setName(serialPortInfo.portName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serialPortInfo.description().isEmpty()) {
|
|
||||||
adapter.setDescription("Unknown");
|
|
||||||
} else {
|
|
||||||
adapter.setDescription(serialPortInfo.description());
|
|
||||||
}
|
|
||||||
adapter.setSystemLocation(serialPortInfo.systemLocation());
|
|
||||||
|
|
||||||
// Check if we recognize this adapter from USB information
|
|
||||||
if (serialPortInfo.manufacturer().toLower().contains("dresden elektronik")) {
|
|
||||||
adapter.setBackendSuggestionAvailable(true);
|
|
||||||
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeDeconz);
|
|
||||||
adapter.setSuggestedBaudRate(38400);
|
|
||||||
} else if (serialPortInfo.manufacturer().toLower().contains("nxp")) {
|
|
||||||
adapter.setBackendSuggestionAvailable(true);
|
|
||||||
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeNxp);
|
|
||||||
adapter.setSuggestedBaudRate(115200);
|
|
||||||
}
|
|
||||||
|
|
||||||
adapters.append(adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return adapters;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList ZigbeeNetworkManager::availableZigbeeBackendTypes()
|
QStringList ZigbeeNetworkManager::availableZigbeeBackendTypes()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,14 +30,14 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "zigbeeadapter.h"
|
#include "zigbeeuartadapter.h"
|
||||||
#include "zigbeenetwork.h"
|
#include "zigbeenetwork.h"
|
||||||
|
|
||||||
class ZigbeeNetworkManager
|
class ZigbeeNetworkManager
|
||||||
{
|
{
|
||||||
Q_GADGET
|
Q_GADGET
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QList<ZigbeeAdapter> availableAdapters();
|
|
||||||
static QStringList availableZigbeeBackendTypes();
|
static QStringList availableZigbeeBackendTypes();
|
||||||
static ZigbeeNetwork *createZigbeeNetwork(Zigbee::ZigbeeBackendType backend, QObject *parent = nullptr);
|
static ZigbeeNetwork *createZigbeeNetwork(Zigbee::ZigbeeBackendType backend, QObject *parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -25,76 +25,76 @@
|
|||||||
*
|
*
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "zigbeeadapter.h"
|
#include "zigbeeuartadapter.h"
|
||||||
|
|
||||||
ZigbeeAdapter::ZigbeeAdapter()
|
ZigbeeUartAdapter::ZigbeeUartAdapter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZigbeeAdapter::name() const
|
QString ZigbeeUartAdapter::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setName(const QString &name)
|
void ZigbeeUartAdapter::setName(const QString &name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZigbeeAdapter::description() const
|
QString ZigbeeUartAdapter::description() const
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setDescription(const QString &description)
|
void ZigbeeUartAdapter::setDescription(const QString &description)
|
||||||
{
|
{
|
||||||
m_description = description;
|
m_description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZigbeeAdapter::systemLocation() const
|
QString ZigbeeUartAdapter::systemLocation() const
|
||||||
{
|
{
|
||||||
return m_systemLocation;
|
return m_systemLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setSystemLocation(const QString &systemLocation)
|
void ZigbeeUartAdapter::setSystemLocation(const QString &systemLocation)
|
||||||
{
|
{
|
||||||
m_systemLocation = systemLocation;
|
m_systemLocation = systemLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZigbeeAdapter::backendSuggestionAvailable() const
|
bool ZigbeeUartAdapter::backendSuggestionAvailable() const
|
||||||
{
|
{
|
||||||
return m_backendSuggestionAvailable;
|
return m_backendSuggestionAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setBackendSuggestionAvailable(bool backendSuggestionAvailable)
|
void ZigbeeUartAdapter::setBackendSuggestionAvailable(bool backendSuggestionAvailable)
|
||||||
{
|
{
|
||||||
m_backendSuggestionAvailable = backendSuggestionAvailable;
|
m_backendSuggestionAvailable = backendSuggestionAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zigbee::ZigbeeBackendType ZigbeeAdapter::suggestedZigbeeBackendType() const
|
Zigbee::ZigbeeBackendType ZigbeeUartAdapter::suggestedZigbeeBackendType() const
|
||||||
{
|
{
|
||||||
return m_suggestedZigbeeBackendType;
|
return m_suggestedZigbeeBackendType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendType backendType)
|
void ZigbeeUartAdapter::setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendType backendType)
|
||||||
{
|
{
|
||||||
m_suggestedZigbeeBackendType = backendType;
|
m_suggestedZigbeeBackendType = backendType;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint32 ZigbeeAdapter::suggestedBaudRate() const
|
qint32 ZigbeeUartAdapter::suggestedBaudRate() const
|
||||||
{
|
{
|
||||||
return m_suggestedBaudRate;
|
return m_suggestedBaudRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeAdapter::setSuggestedBaudRate(qint32 baudRate)
|
void ZigbeeUartAdapter::setSuggestedBaudRate(qint32 baudRate)
|
||||||
{
|
{
|
||||||
m_suggestedBaudRate = baudRate;
|
m_suggestedBaudRate = baudRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter)
|
QDebug operator<<(QDebug debug, const ZigbeeUartAdapter &adapter)
|
||||||
{
|
{
|
||||||
debug.nospace() << "ZigbeeAdapter(" << adapter.name() << " - " << adapter.description();
|
debug.nospace() << "ZigbeeUartAdapter(" << adapter.name() << " - " << adapter.description();
|
||||||
debug.nospace() << ", " << adapter.systemLocation();
|
debug.nospace() << ", " << adapter.systemLocation();
|
||||||
if (adapter.backendSuggestionAvailable()) {
|
if (adapter.backendSuggestionAvailable()) {
|
||||||
debug.nospace() << "Suggested backend: " << adapter.suggestedZigbeeBackendType();
|
debug.nospace() << "Suggested backend: " << adapter.suggestedZigbeeBackendType();
|
||||||
@ -25,26 +25,18 @@
|
|||||||
*
|
*
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifndef ZIGBEEADAPTER_H
|
#ifndef ZIGBEEUARTADAPTER_H
|
||||||
#define ZIGBEEADAPTER_H
|
#define ZIGBEEUARTADAPTER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "zigbee.h"
|
#include "zigbee.h"
|
||||||
|
|
||||||
class ZigbeeAdapter
|
class ZigbeeUartAdapter
|
||||||
{
|
{
|
||||||
Q_GADGET
|
|
||||||
Q_PROPERTY(QString name READ name)
|
|
||||||
Q_PROPERTY(QString description READ description)
|
|
||||||
Q_PROPERTY(QString systemLocation READ systemLocation)
|
|
||||||
Q_PROPERTY(bool backendSuggestionAvailable READ backendSuggestionAvailable)
|
|
||||||
Q_PROPERTY(Zigbee::ZigbeeBackendType suggestedZigbeeBackendType READ suggestedZigbeeBackendType)
|
|
||||||
Q_PROPERTY(qint32 suggestedBaudRate READ suggestedBaudRate)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ZigbeeAdapter();
|
explicit ZigbeeUartAdapter();
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
@ -74,7 +66,9 @@ private:
|
|||||||
qint32 m_suggestedBaudRate = 38400;
|
qint32 m_suggestedBaudRate = 38400;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter);
|
Q_DECLARE_METATYPE(ZigbeeUartAdapter)
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeUartAdapter &adapter);
|
||||||
|
|
||||||
|
|
||||||
#endif // ZIGBEEADAPTER_H
|
#endif // ZIGBEEADAPTER_H
|
||||||
241
libnymea-zigbee/zigbeeuartadaptermonitor.cpp
Normal file
241
libnymea-zigbee/zigbeeuartadaptermonitor.cpp
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* 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 "zigbeeuartadaptermonitor.h"
|
||||||
|
#include "loggingcategory.h"
|
||||||
|
|
||||||
|
#include <QSerialPortInfo>
|
||||||
|
|
||||||
|
ZigbeeUartAdapterMonitor::ZigbeeUartAdapterMonitor(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
qRegisterMetaType<ZigbeeUartAdapter>();
|
||||||
|
|
||||||
|
m_udev = udev_new();
|
||||||
|
if (!m_udev) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Could not initialize udev for the adapter monitor";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read initially all tty devices
|
||||||
|
struct udev_enumerate *enumerate = udev_enumerate_new(m_udev);
|
||||||
|
if (!enumerate) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Could not create udev enumerate for initial device reading for the adapter monitor.";
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
udev_enumerate_add_match_subsystem(enumerate, "tty");
|
||||||
|
|
||||||
|
if (udev_enumerate_scan_devices(enumerate) < 0) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Failed to scan devices from udev enumerate.";
|
||||||
|
udev_enumerate_unref(enumerate);
|
||||||
|
enumerate = nullptr;
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "Load initial list of available serial ports...";
|
||||||
|
struct udev_list_entry *devices = nullptr;
|
||||||
|
devices = udev_enumerate_get_list_entry(enumerate);
|
||||||
|
struct udev_list_entry *dev_list_entry = nullptr;
|
||||||
|
udev_list_entry_foreach(dev_list_entry, devices) {
|
||||||
|
struct udev_device *device = nullptr;
|
||||||
|
const char *path;
|
||||||
|
path = udev_list_entry_get_name(dev_list_entry);
|
||||||
|
device = udev_device_new_from_syspath(m_udev, path);
|
||||||
|
|
||||||
|
// Print properties
|
||||||
|
struct udev_list_entry *properties = udev_device_get_properties_list_entry(device);
|
||||||
|
struct udev_list_entry *property_list_entry = nullptr;
|
||||||
|
udev_list_entry_foreach(property_list_entry, properties) {
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " - Property" << udev_list_entry_get_name(property_list_entry) << udev_list_entry_get_value(property_list_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString devicePath = QString::fromLatin1(udev_device_get_property_value(device,"DEVNAME"));
|
||||||
|
QString manufacturerString = QString::fromLatin1(udev_device_get_property_value(device,"ID_VENDOR_ENC"));
|
||||||
|
QString descriptionString = QString::fromLatin1(udev_device_get_property_value(device,"ID_MODEL_ENC"));
|
||||||
|
QString serialNumberString = QString::fromLatin1(udev_device_get_property_value(device, "ID_SERIAL_SHORT"));
|
||||||
|
|
||||||
|
// Clean up this device since we have all information
|
||||||
|
udev_device_unref(device);
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "[+]" << devicePath << manufacturerString << descriptionString << serialNumberString;
|
||||||
|
addAdapterInternally(devicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
udev_enumerate_unref(enumerate);
|
||||||
|
enumerate = nullptr;
|
||||||
|
|
||||||
|
// Create udev monitor
|
||||||
|
m_monitor = udev_monitor_new_from_netlink(m_udev, "udev");
|
||||||
|
if (!m_monitor) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Could not initialize udev monitor.";
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set monitor filter to tty subsystem
|
||||||
|
if (udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "tty", nullptr) < 0) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Could not set subsystem device type filter to tty.";
|
||||||
|
udev_monitor_unref(m_monitor);
|
||||||
|
m_monitor = nullptr;
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the monitor
|
||||||
|
if (udev_monitor_enable_receiving(m_monitor) < 0) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Could not enable udev monitor.";
|
||||||
|
udev_monitor_unref(m_monitor);
|
||||||
|
m_monitor = nullptr;
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create socket notifier for read
|
||||||
|
int socketDescriptor = udev_monitor_get_fd(m_monitor);
|
||||||
|
m_notifier = new QSocketNotifier(socketDescriptor, QSocketNotifier::Read, this);
|
||||||
|
connect(m_notifier, &QSocketNotifier::activated, this, [this, socketDescriptor](int socket){
|
||||||
|
// Make sure the socket matches
|
||||||
|
if (socketDescriptor != socket) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "socket != socketdescriptor";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create udev device
|
||||||
|
udev_device *device = udev_monitor_receive_device(m_monitor);
|
||||||
|
if (!device) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "Got socket sotification but could not read device information.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString actionString = QString::fromLatin1(udev_device_get_action(device));
|
||||||
|
QString devicePath = QString::fromLatin1(udev_device_get_property_value(device,"DEVNAME"));
|
||||||
|
QString manufacturerString = QString::fromLatin1(udev_device_get_property_value(device,"ID_VENDOR_ENC"));
|
||||||
|
QString descriptionString = QString::fromLatin1(udev_device_get_property_value(device,"ID_MODEL_ENC"));
|
||||||
|
QString serialNumberString = QString::fromLatin1(udev_device_get_property_value(device, "ID_SERIAL_SHORT"));
|
||||||
|
|
||||||
|
// Clean udev device
|
||||||
|
udev_device_unref(device);
|
||||||
|
|
||||||
|
// Make sure we know the action
|
||||||
|
if (actionString.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (actionString == "add") {
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "[+]" << devicePath << serialNumberString;
|
||||||
|
if (!m_availableAdapters.contains(devicePath)) {
|
||||||
|
addAdapterInternally(devicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionString == "remove") {
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "[-]" << devicePath << serialNumberString;
|
||||||
|
if (m_availableAdapters.contains(devicePath)) {
|
||||||
|
ZigbeeUartAdapter adapter = m_availableAdapters.take(devicePath);
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "Removed" << adapter;
|
||||||
|
emit adapterRemoved(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_notifier->setEnabled(true);
|
||||||
|
m_isValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ZigbeeUartAdapter> ZigbeeUartAdapterMonitor::availableAdapters() const
|
||||||
|
{
|
||||||
|
return m_availableAdapters.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeUartAdapterMonitor::isValid() const
|
||||||
|
{
|
||||||
|
return m_isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeUartAdapterMonitor::addAdapterInternally(const QString &systemLocation)
|
||||||
|
{
|
||||||
|
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
|
||||||
|
if (serialPortInfo.systemLocation() != systemLocation)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_availableAdapters.keys().contains(systemLocation)) {
|
||||||
|
qCWarning(dcZigbeeAdapterMonitor()) << "The adapter" << systemLocation << "has already been added to the monitor.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "Adapter candidate" << serialPortInfo.portName();
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " Description:" << serialPortInfo.description();
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " System location:" << serialPortInfo.systemLocation();
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " Manufacturer:" << serialPortInfo.manufacturer();
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " Serialnumber:" << serialPortInfo.serialNumber();
|
||||||
|
|
||||||
|
if (serialPortInfo.hasProductIdentifier()) {
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " Product identifier:" << serialPortInfo.productIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serialPortInfo.hasVendorIdentifier()) {
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << " Vendor identifier:" << serialPortInfo.vendorIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we recognize this controller
|
||||||
|
ZigbeeUartAdapter adapter;
|
||||||
|
if (serialPortInfo.portName().isEmpty()) {
|
||||||
|
adapter.setName("Zigbee adapter");
|
||||||
|
} else {
|
||||||
|
adapter.setName(serialPortInfo.portName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serialPortInfo.description().isEmpty()) {
|
||||||
|
adapter.setDescription("Unknown");
|
||||||
|
} else {
|
||||||
|
adapter.setDescription(serialPortInfo.description());
|
||||||
|
}
|
||||||
|
adapter.setSystemLocation(serialPortInfo.systemLocation());
|
||||||
|
|
||||||
|
// Check if we recognize this adapter from USB information
|
||||||
|
if (serialPortInfo.manufacturer().toLower().contains("dresden elektronik")) {
|
||||||
|
adapter.setBackendSuggestionAvailable(true);
|
||||||
|
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeDeconz);
|
||||||
|
adapter.setSuggestedBaudRate(38400);
|
||||||
|
} else if (serialPortInfo.manufacturer().toLower().contains("nxp")) {
|
||||||
|
adapter.setBackendSuggestionAvailable(true);
|
||||||
|
adapter.setSuggestedZigbeeBackendType(Zigbee::ZigbeeBackendTypeNxp);
|
||||||
|
adapter.setSuggestedBaudRate(115200);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeAdapterMonitor()) << "Added" << adapter;
|
||||||
|
m_availableAdapters.insert(adapter.systemLocation(), adapter);
|
||||||
|
emit adapterAdded(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
64
libnymea-zigbee/zigbeeuartadaptermonitor.h
Normal file
64
libnymea-zigbee/zigbeeuartadaptermonitor.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* 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 ZIGBEEUARTADAPTERMONITOR_H
|
||||||
|
#define ZIGBEEUARTADAPTERMONITOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
|
||||||
|
#include <libudev.h>
|
||||||
|
|
||||||
|
#include "zigbeeuartadapter.h"
|
||||||
|
|
||||||
|
class ZigbeeUartAdapterMonitor : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ZigbeeUartAdapterMonitor(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QList<ZigbeeUartAdapter> availableAdapters() const;
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isValid = false;
|
||||||
|
struct udev *m_udev = nullptr;
|
||||||
|
struct udev_monitor *m_monitor = nullptr;
|
||||||
|
QSocketNotifier *m_notifier = nullptr;
|
||||||
|
|
||||||
|
QHash<QString, ZigbeeUartAdapter> m_availableAdapters;
|
||||||
|
|
||||||
|
void addAdapterInternally(const QString &systemLocation);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void adapterAdded(const ZigbeeUartAdapter &adapter);
|
||||||
|
void adapterRemoved(const ZigbeeUartAdapter &adapter);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ZIGBEEUARTADAPTERMONITOR_H
|
||||||
Reference in New Issue
Block a user