Remove settings and leave that to the stack using application

This commit is contained in:
Simon Stürz 2020-10-29 11:45:28 +01:00
parent 097254756e
commit db146a38d0
10 changed files with 125 additions and 59 deletions

View File

@ -32,8 +32,8 @@
#include <QDataStream> #include <QDataStream>
ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(QObject *parent) : ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(const QUuid &networkUuid, QObject *parent) :
ZigbeeNetwork(parent) ZigbeeNetwork(networkUuid, parent)
{ {
m_controller = new ZigbeeBridgeControllerDeconz(this); m_controller = new ZigbeeBridgeControllerDeconz(this);
connect(m_controller, &ZigbeeBridgeControllerDeconz::availableChanged, this, &ZigbeeNetworkDeconz::onControllerAvailableChanged); connect(m_controller, &ZigbeeBridgeControllerDeconz::availableChanged, this, &ZigbeeNetworkDeconz::onControllerAvailableChanged);
@ -59,6 +59,11 @@ ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
return qobject_cast<ZigbeeBridgeController *>(m_controller); return qobject_cast<ZigbeeBridgeController *>(m_controller);
} }
Zigbee::ZigbeeBackendType ZigbeeNetworkDeconz::backendType() const
{
return Zigbee::ZigbeeBackendTypeDeconz;
}
ZigbeeNetworkReply *ZigbeeNetworkDeconz::sendRequest(const ZigbeeNetworkRequest &request) ZigbeeNetworkReply *ZigbeeNetworkDeconz::sendRequest(const ZigbeeNetworkRequest &request)
{ {
ZigbeeNetworkReply *reply = createNetworkReply(request); ZigbeeNetworkReply *reply = createNetworkReply(request);

View File

@ -49,9 +49,10 @@ public:
}; };
Q_ENUM(CreateNetworkState) Q_ENUM(CreateNetworkState)
explicit ZigbeeNetworkDeconz(QObject *parent = nullptr); explicit ZigbeeNetworkDeconz(const QUuid &networkUuid, QObject *parent = nullptr);
ZigbeeBridgeController *bridgeController() const override; ZigbeeBridgeController *bridgeController() const override;
Zigbee::ZigbeeBackendType backendType() const override;
// Sending an APSDE-DATA.request, will be finished on APSDE-DATA.confirm // Sending an APSDE-DATA.request, will be finished on APSDE-DATA.confirm
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override; ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;

View File

@ -31,8 +31,8 @@
#include <QDataStream> #include <QDataStream>
ZigbeeNetworkNxp::ZigbeeNetworkNxp(QObject *parent) : ZigbeeNetworkNxp::ZigbeeNetworkNxp(const QUuid &networkUuid, QObject *parent) :
ZigbeeNetwork(parent) ZigbeeNetwork(networkUuid, parent)
{ {
m_controller = new ZigbeeBridgeControllerNxp(this); m_controller = new ZigbeeBridgeControllerNxp(this);
connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged); connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged);
@ -71,6 +71,11 @@ ZigbeeBridgeController *ZigbeeNetworkNxp::bridgeController() const
return qobject_cast<ZigbeeBridgeController *>(m_controller); return qobject_cast<ZigbeeBridgeController *>(m_controller);
} }
Zigbee::ZigbeeBackendType ZigbeeNetworkNxp::backendType() const
{
return Zigbee::ZigbeeBackendTypeNxp;
}
ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &request) ZigbeeNetworkReply *ZigbeeNetworkNxp::sendRequest(const ZigbeeNetworkRequest &request)
{ {
ZigbeeNetworkReply *reply = createNetworkReply(request); ZigbeeNetworkReply *reply = createNetworkReply(request);

View File

@ -40,10 +40,10 @@ class ZigbeeNetworkNxp : public ZigbeeNetwork
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ZigbeeNetworkNxp(QObject *parent = nullptr); explicit ZigbeeNetworkNxp(const QUuid &networkUuid, QObject *parent = nullptr);
ZigbeeBridgeController *bridgeController() const override; ZigbeeBridgeController *bridgeController() const override;
Zigbee::ZigbeeBackendType backendType() const override;
ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override; ZigbeeNetworkReply *sendRequest(const ZigbeeNetworkRequest &request) override;
ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe); ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);

View File

@ -34,12 +34,18 @@
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : ZigbeeNetwork::ZigbeeNetwork(const QUuid &networkUuid, QObject *parent) :
QObject(parent) QObject(parent),
m_networkUuid(networkUuid)
{ {
} }
QUuid ZigbeeNetwork::networkUuid() const
{
return m_networkUuid;
}
ZigbeeNetwork::State ZigbeeNetwork::state() const ZigbeeNetwork::State ZigbeeNetwork::state() const
{ {
return m_state; return m_state;
@ -50,18 +56,17 @@ ZigbeeNetwork::Error ZigbeeNetwork::error() const
return m_error; return m_error;
} }
QString ZigbeeNetwork::settingsFilenName() const QDir ZigbeeNetwork::settingsDirectory() const
{ {
return m_settingsFileName; return m_settingsDirectory;
} }
void ZigbeeNetwork::setSettingsFileName(const QString &settingsFileName) void ZigbeeNetwork::setSettingsDirectory(const QDir &settingsDirectory)
{ {
qCDebug(dcZigbeeNetwork()) << "Using settings file" << settingsFileName; qCDebug(dcZigbeeNetwork()) << "Using settings directory" << settingsDirectory.absolutePath();
m_settingsFileName = settingsFileName; m_settingsDirectory = settingsDirectory;
emit settingsFileNameChanged(m_settingsFileName); emit settingsDirectoryChanged(m_settingsDirectory);
m_settingsDirectory = QDir(QFileInfo(m_settingsFileName).absolutePath());
bridgeController()->setSettingsDirectory(m_settingsDirectory); bridgeController()->setSettingsDirectory(m_settingsDirectory);
} }
@ -93,6 +98,20 @@ void ZigbeeNetwork::setSerialBaudrate(qint32 baudrate)
emit serialBaudrateChanged(m_serialBaudrate); emit serialBaudrateChanged(m_serialBaudrate);
} }
ZigbeeAddress ZigbeeNetwork::macAddress() const
{
return m_macAddress;
}
void ZigbeeNetwork::setMacAddress(const ZigbeeAddress &zigbeeAddress)
{
if (m_macAddress == zigbeeAddress)
return;
m_macAddress = zigbeeAddress;
emit macAddressChanged(m_macAddress);
}
quint16 ZigbeeNetwork::panId() quint16 ZigbeeNetwork::panId()
{ {
return m_panId; return m_panId;
@ -315,39 +334,39 @@ ZigbeeNode *ZigbeeNetwork::createNode(quint16 shortAddress, const ZigbeeAddress
void ZigbeeNetwork::saveNetwork() void ZigbeeNetwork::saveNetwork()
{ {
qCDebug(dcZigbeeNetwork()) << "Save current network configuration to" << m_settingsFileName; // qCDebug(dcZigbeeNetwork()) << "Save current network configuration to" << m_settingsFileName;
QSettings settings(m_settingsFileName, QSettings::IniFormat, this); // QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
settings.beginGroup("ZigbeeNetwork"); // settings.beginGroup("ZigbeeNetwork");
settings.setValue("panId", panId()); // settings.setValue("panId", panId());
settings.setValue("channel", channel()); // settings.setValue("channel", channel());
settings.setValue("networkKey", securityConfiguration().networkKey().toString()); // settings.setValue("networkKey", securityConfiguration().networkKey().toString());
settings.setValue("trustCenterLinkKey", securityConfiguration().globalTrustCenterLinkKey().toString()); // settings.setValue("trustCenterLinkKey", securityConfiguration().globalTrustCenterLinkKey().toString());
settings.endGroup(); // settings.endGroup();
} }
void ZigbeeNetwork::loadNetwork() void ZigbeeNetwork::loadNetwork()
{ {
qCDebug(dcZigbeeNetwork()) << "Load current network configuration from" << m_settingsFileName; qCDebug(dcZigbeeNetwork()) << "Loading network from settings directory" << m_settingsDirectory.absolutePath();
if (!m_database) { if (!m_database) {
QDir storagePath = QFileInfo(m_settingsFileName).absoluteDir(); QString networkDatabaseFileName = m_settingsDirectory.absolutePath() + QDir::separator() + QString("zigbee-network-%1.db").arg(m_networkUuid.toString());
m_database = new ZigbeeNetworkDatabase(this, storagePath.absolutePath() + QDir::separator() + "zigbee-network.db", this); qCDebug(dcZigbeeNetwork()) << "Using ZigBee network database" << QFileInfo(networkDatabaseFileName).fileName();
m_database = new ZigbeeNetworkDatabase(this, networkDatabaseFileName, this);
} }
QSettings settings(m_settingsFileName, QSettings::IniFormat, this); // QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
settings.beginGroup("ZigbeeNetwork"); // settings.beginGroup("ZigbeeNetwork");
quint16 panId = static_cast<quint16>(settings.value("panId", 0).toUInt()); // quint16 panId = static_cast<quint16>(settings.value("panId", 0).toUInt());
setPanId(panId); // setPanId(panId);
setChannel(settings.value("channel", 0).toUInt()); // setChannel(settings.value("channel", 0).toUInt());
ZigbeeNetworkKey netKey(settings.value("networkKey", QString()).toString()); // ZigbeeNetworkKey netKey(settings.value("networkKey", QString()).toString());
if (netKey.isValid()) // if (netKey.isValid())
m_securityConfiguration.setNetworkKey(netKey); // m_securityConfiguration.setNetworkKey(netKey);
ZigbeeNetworkKey tcKey(settings.value("trustCenterLinkKey", QString("5A6967426565416C6C69616E63653039")).toString()); // ZigbeeNetworkKey tcKey(settings.value("trustCenterLinkKey", QString("5A6967426565416C6C69616E63653039")).toString());
if (!tcKey.isValid()) // if (!tcKey.isValid())
m_securityConfiguration.setGlobalTrustCenterlinkKey(tcKey); // m_securityConfiguration.setGlobalTrustCenterlinkKey(tcKey);
settings.endGroup(); // Network // settings.endGroup(); // Network
QList<ZigbeeNode *> nodes = m_database->loadNodes(); QList<ZigbeeNode *> nodes = m_database->loadNodes();
foreach (ZigbeeNode *node, nodes) { foreach (ZigbeeNode *node, nodes) {
@ -358,25 +377,32 @@ void ZigbeeNetwork::loadNetwork()
void ZigbeeNetwork::clearSettings() void ZigbeeNetwork::clearSettings()
{ {
// Note: this clears the database
qCDebug(dcZigbeeNetwork()) << "Remove zigbee nodes from network"; qCDebug(dcZigbeeNetwork()) << "Remove zigbee nodes from network";
foreach (ZigbeeNode *node, m_nodes) { foreach (ZigbeeNode *node, m_nodes) {
removeNode(node); removeNode(node);
} }
qCDebug(dcZigbeeNetwork()) << "Clear all uninitialized nodes";
foreach (ZigbeeNode *node, m_uninitializedNodes) { foreach (ZigbeeNode *node, m_uninitializedNodes) {
qCDebug(dcZigbeeNetwork()) << "Remove uninitialized" << node;
m_uninitializedNodes.removeAll(node); m_uninitializedNodes.removeAll(node);
node->deleteLater(); node->deleteLater();
} }
qCDebug(dcZigbeeNetwork()) << "Clear network settings" << m_settingsFileName; qCDebug(dcZigbeeNetwork()) << "Delete network database";
QSettings settings(m_settingsFileName, QSettings::IniFormat, this); if (m_database) {
settings.clear(); if (!m_database->wipeDatabase()) {
qCWarning(dcZigbeeNetwork()) << "Failed to wipe the network database" << m_database->databaseName();
}
}
// Reset network configurations // Reset network configurations
qCDebug(dcZigbeeNetwork()) << "Clear network properties"; qCDebug(dcZigbeeNetwork()) << "Clear network properties";
m_extendedPanId = 0; setExtendedPanId(0);
m_channel = 0; setChannel(0);
m_securityConfiguration.clear(); setSecurityConfiguration(ZigbeeSecurityConfiguration());
setState(StateUninitialized);
m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator; m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator;
} }
@ -512,6 +538,7 @@ void ZigbeeNetwork::finishNetworkReply(ZigbeeNetworkReply *reply, ZigbeeNetworkR
qCWarning(dcZigbeeNetwork()) << "Failed to send request to device" << reply->request() << reply->error(); qCWarning(dcZigbeeNetwork()) << "Failed to send request to device" << reply->request() << reply->error();
break; break;
} }
// Stop the timer // Stop the timer
reply->m_timer->stop(); reply->m_timer->stop();

View File

@ -29,9 +29,9 @@
#define ZIGBEENETWORK_H #define ZIGBEENETWORK_H
#include <QDir> #include <QDir>
#include <QUuid>
#include <QObject> #include <QObject>
#include <QSettings> #include <QSettings>
#include <QSqlDatabase> #include <QSqlDatabase>
#include "zigbeenode.h" #include "zigbeenode.h"
@ -64,16 +64,19 @@ public:
}; };
Q_ENUM(Error) Q_ENUM(Error)
explicit ZigbeeNetwork(QObject *parent = nullptr); explicit ZigbeeNetwork(const QUuid &networkUuid, QObject *parent = nullptr);
QUuid networkUuid() const;
State state() const; State state() const;
Error error() const; Error error() const;
QString settingsFilenName() const; QDir settingsDirectory() const;
void setSettingsFileName(const QString &settingsFileName); void setSettingsDirectory(const QDir &settingsDirectory);
virtual ZigbeeBridgeController *bridgeController() const = 0; virtual ZigbeeBridgeController *bridgeController() const = 0;
virtual Zigbee::ZigbeeBackendType backendType() const = 0;
// Serial port configuration // Serial port configuration
QString serialPortName() const; QString serialPortName() const;
@ -82,6 +85,9 @@ public:
qint32 serialBaudrate() const; qint32 serialBaudrate() const;
void setSerialBaudrate(qint32 baudrate); void setSerialBaudrate(qint32 baudrate);
ZigbeeAddress macAddress() const;
void setMacAddress(const ZigbeeAddress &zigbeeAddress);
// Network configurations // Network configurations
quint16 panId(); quint16 panId();
void setPanId(quint16 panId); void setPanId(quint16 panId);
@ -119,11 +125,13 @@ public:
void removeZigbeeNode(const ZigbeeAddress &address); void removeZigbeeNode(const ZigbeeAddress &address);
private: private:
QUuid m_networkUuid;
State m_state = StateUninitialized; State m_state = StateUninitialized;
// Serial port configuration // Serial port configuration
QString m_serialPortName = "/dev/ttyUSB0"; QString m_serialPortName = "/dev/ttyUSB0";
qint32 m_serialBaudrate = 115200; qint32 m_serialBaudrate = 115200;
ZigbeeAddress m_macAddress;
// Continuouse ASP sequence number for network requests // Continuouse ASP sequence number for network requests
quint8 m_sequenceNumber = 0; quint8 m_sequenceNumber = 0;
@ -136,7 +144,6 @@ private:
ZigbeeDeviceProfile::NodeType m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator; ZigbeeDeviceProfile::NodeType m_nodeType = ZigbeeDeviceProfile::NodeTypeCoordinator;
// Network storage // Network storage
QString m_settingsFileName = "/etc/nymea/nymea-zigbee.conf";
QDir m_settingsDirectory = QDir("/etc/nymea/"); QDir m_settingsDirectory = QDir("/etc/nymea/");
QList<ZigbeeNode *> m_nodes; QList<ZigbeeNode *> m_nodes;
QList<ZigbeeNode *> m_uninitializedNodes; QList<ZigbeeNode *> m_uninitializedNodes;
@ -181,9 +188,10 @@ protected:
void startWaitingReply(ZigbeeNetworkReply *reply); void startWaitingReply(ZigbeeNetworkReply *reply);
signals: signals:
void settingsFileNameChanged(const QString &settingsFileName); void settingsDirectoryChanged(const QDir &settingsDirectory);
void serialPortNameChanged(const QString &serialPortName); void serialPortNameChanged(const QString &serialPortName);
void serialBaudrateChanged(qint32 serialBaudrate); void serialBaudrateChanged(qint32 serialBaudrate);
void macAddressChanged(const ZigbeeAddress &macAddress);
void panIdChanged(quint16 panId); void panIdChanged(quint16 panId);
void extendedPanIdChanged(quint64 extendedPanId); void extendedPanIdChanged(quint64 extendedPanId);

View File

@ -36,10 +36,11 @@
ZigbeeNetworkDatabase::ZigbeeNetworkDatabase(ZigbeeNetwork *network, const QString &databaseName, QObject *parent) : ZigbeeNetworkDatabase::ZigbeeNetworkDatabase(ZigbeeNetwork *network, const QString &databaseName, QObject *parent) :
QObject(parent), QObject(parent),
m_network(network) m_network(network),
m_databaseName(databaseName)
{ {
m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "zigbee"); m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "zigbee");
m_db.setDatabaseName(databaseName); m_db.setDatabaseName(m_databaseName);
qCDebug(dcZigbeeNetworkDatabase()) << "Opening zigbee network database" << m_db.databaseName(); qCDebug(dcZigbeeNetworkDatabase()) << "Opening zigbee network database" << m_db.databaseName();
if (!m_db.isValid()) { if (!m_db.isValid()) {
@ -63,6 +64,11 @@ ZigbeeNetworkDatabase::~ZigbeeNetworkDatabase()
} }
} }
QString ZigbeeNetworkDatabase::databaseName() const
{
return m_databaseName;
}
QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes() QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes()
{ {
qCDebug(dcZigbeeNetworkDatabase()) << "Loading nodes from database" << m_db.databaseName(); qCDebug(dcZigbeeNetworkDatabase()) << "Loading nodes from database" << m_db.databaseName();
@ -177,6 +183,16 @@ bool ZigbeeNetworkDatabase::wipeDatabase()
qCWarning(dcZigbeeNetworkDatabase()) << "Could not delete all node database entries." << m_db.lastError().databaseText() << m_db.lastError().driverText(); qCWarning(dcZigbeeNetworkDatabase()) << "Could not delete all node database entries." << m_db.lastError().databaseText() << m_db.lastError().driverText();
return false; return false;
} }
m_db.close();
// Delete database file
QFile databaseFile(m_databaseName);
if (databaseFile.exists()) {
if (!databaseFile.remove()) {
qCWarning(dcZigbeeNetworkDatabase()) << "Could not delete database file" << m_databaseName;
return false;
}
}
return true; return true;
} }

View File

@ -46,11 +46,15 @@ public:
explicit ZigbeeNetworkDatabase(ZigbeeNetwork *network, const QString &databaseName, QObject *parent = nullptr); explicit ZigbeeNetworkDatabase(ZigbeeNetwork *network, const QString &databaseName, QObject *parent = nullptr);
~ZigbeeNetworkDatabase(); ~ZigbeeNetworkDatabase();
QString databaseName() const;
QList<ZigbeeNode *> loadNodes(); QList<ZigbeeNode *> loadNodes();
bool wipeDatabase(); bool wipeDatabase();
private: private:
ZigbeeNetwork *m_network = nullptr; ZigbeeNetwork *m_network = nullptr;
QString m_databaseName;
QSqlDatabase m_db; QSqlDatabase m_db;
bool initDatabase(); bool initDatabase();

View File

@ -38,16 +38,16 @@ QStringList ZigbeeNetworkManager::availableZigbeeBackendTypes()
return {"deCONZ", "NXP"}; return {"deCONZ", "NXP"};
} }
ZigbeeNetwork *ZigbeeNetworkManager::createZigbeeNetwork(Zigbee::ZigbeeBackendType backend, QObject *parent) ZigbeeNetwork *ZigbeeNetworkManager::createZigbeeNetwork(const QUuid &networkUuid, Zigbee::ZigbeeBackendType backend, QObject *parent)
{ {
// Note: required for generating random PAN ID // Note: required for generating random PAN ID
srand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000)); srand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
switch (backend) { switch (backend) {
case Zigbee::ZigbeeBackendTypeNxp: case Zigbee::ZigbeeBackendTypeNxp:
return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkNxp(parent)); return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkNxp(networkUuid, parent));
case Zigbee::ZigbeeBackendTypeDeconz: case Zigbee::ZigbeeBackendTypeDeconz:
return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkDeconz(parent)); return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkDeconz(networkUuid, parent));
} }
return nullptr; return nullptr;

View File

@ -30,8 +30,8 @@
#include <QObject> #include <QObject>
#include "zigbeeuartadapter.h"
#include "zigbeenetwork.h" #include "zigbeenetwork.h"
#include "zigbeeuartadapter.h"
class ZigbeeNetworkManager class ZigbeeNetworkManager
{ {
@ -39,7 +39,7 @@ class ZigbeeNetworkManager
public: public:
static QStringList availableZigbeeBackendTypes(); static QStringList availableZigbeeBackendTypes();
static ZigbeeNetwork *createZigbeeNetwork(Zigbee::ZigbeeBackendType backend, QObject *parent = nullptr); static ZigbeeNetwork *createZigbeeNetwork(const QUuid &networkUuid, Zigbee::ZigbeeBackendType backend, QObject *parent = nullptr);
}; };
Q_DECLARE_METATYPE(ZigbeeNetworkManager) Q_DECLARE_METATYPE(ZigbeeNetworkManager)