Implement auto update mechanism for the nxp controller and initial flash if communication is not possible
parent
5f2560d380
commit
9483610386
|
|
@ -0,0 +1,188 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "firmwareupdatehandlernxp.h"
|
||||
#include "loggingcategory.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
|
||||
/*
|
||||
* [UpdateProvider]
|
||||
* updateBinary=/usr/bin/maveo-zigbee-flasher
|
||||
* updateReleaseFile=/usr/share/maveo-zigbee-flasher/firmware/release.json
|
||||
*/
|
||||
|
||||
FirmwareUpdateHandlerNxp::FirmwareUpdateHandlerNxp(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FirmwareUpdateHandlerNxp::FirmwareUpdateHandlerNxp(const QFileInfo &updateProviderConfgigurationFileInfo, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_updateProviderConfgigurationFileInfo(updateProviderConfgigurationFileInfo)
|
||||
{
|
||||
qCDebug(dcZigbeeController()) << "Initialize NXP firmware update provider";
|
||||
|
||||
QSettings configuration(updateProviderConfgigurationFileInfo.absoluteFilePath(), QSettings::IniFormat, this);
|
||||
configuration.beginGroup("UpdateProvider");
|
||||
|
||||
// Verify the update provider binary
|
||||
m_updateBinary = configuration.value("updateBinary").toString();
|
||||
if (m_updateBinary.isEmpty()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the update binary is not specified in" << m_updateProviderConfgigurationFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo updateBinaryFileInfo(m_updateBinary);
|
||||
if (!updateBinaryFileInfo.exists()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the update binary does not exist" << updateBinaryFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!updateBinaryFileInfo.isExecutable()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the update binary is not executable" << updateBinaryFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify update release file and corresponding update file and version
|
||||
m_updateReleaseFilePath = configuration.value("updateReleaseFile").toString();
|
||||
QFileInfo releaseFileInfo(m_updateReleaseFilePath);
|
||||
if (! releaseFileInfo.exists()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the release file does not exist" << releaseFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the release file
|
||||
QFile releaseFile(releaseFileInfo.absoluteFilePath());
|
||||
if (!releaseFile.open(QFile::ReadOnly)) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but could not open update release file" << releaseFileInfo.absoluteFilePath() << releaseFile.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray releaseFileData = releaseFile.readAll();
|
||||
releaseFile.close();
|
||||
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(releaseFileData, &jsonError);
|
||||
if (jsonError.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but could not parse the release file" << releaseFileInfo.absoluteFilePath() << jsonError.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap releaseMap = jsonDoc.toVariant().toMap();
|
||||
if (!releaseMap.contains("version")) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the release file does not contain available version information" << releaseFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
m_availableFirmwareVersion = releaseMap.value("version").toString();
|
||||
if (m_availableFirmwareVersion.isEmpty()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the version in the release file is empty" << releaseFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!releaseMap.contains("firmware")) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the release file does not contain available firmware file name" << releaseFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
m_availableFirmwareFileName = releaseMap.value("firmware").toString();
|
||||
if (m_availableFirmwareFileName.isEmpty()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the firmware file path in the release file is empty" << releaseFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo firmwareFileInfo(releaseFileInfo.canonicalPath() + QDir::separator() + m_availableFirmwareFileName);
|
||||
if (!firmwareFileInfo.exists()) {
|
||||
qCWarning(dcZigbeeController()) << "Update provider configuration available but the update firmware file does not exist" << firmwareFileInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeController()) << "Firmware update prvider available:" << firmwareFileInfo.absoluteFilePath() << "Version:" << m_availableFirmwareVersion;
|
||||
configuration.endGroup();
|
||||
|
||||
m_updateProcess = new QProcess(this);
|
||||
m_updateProcess->setProcessChannelMode(QProcess::MergedChannels);
|
||||
m_updateProcess->setProgram(m_updateBinary);
|
||||
|
||||
connect(m_updateProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qCDebug(dcZigbeeController()) << "Update process finihed" << exitCode << exitStatus;
|
||||
if (exitCode != 0) {
|
||||
emit updateFinished(false);
|
||||
} else {
|
||||
emit updateFinished(true);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_updateProcess, &QProcess::readyRead, [=]() {
|
||||
qCDebug(dcZigbeeController()) << "Update process:" << qUtf8Printable(m_updateProcess->readAll().replace(0x1B, '\r'));
|
||||
});
|
||||
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
bool FirmwareUpdateHandlerNxp::updateRunning() const
|
||||
{
|
||||
return m_updateProcess->state() != QProcess::NotRunning;
|
||||
}
|
||||
|
||||
bool FirmwareUpdateHandlerNxp::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
QString FirmwareUpdateHandlerNxp::updateBinary() const
|
||||
{
|
||||
return m_updateBinary;
|
||||
}
|
||||
|
||||
QString FirmwareUpdateHandlerNxp::availableFirmwareFileName() const
|
||||
{
|
||||
return m_availableFirmwareFileName;
|
||||
}
|
||||
|
||||
QString FirmwareUpdateHandlerNxp::availableFirmwareVersion() const
|
||||
{
|
||||
return m_availableFirmwareVersion;
|
||||
}
|
||||
|
||||
void FirmwareUpdateHandlerNxp::startUpdate()
|
||||
{
|
||||
if (!m_updateProcess) {
|
||||
qCWarning(dcZigbeeController()) << "Cannot start update process. The updater is not vaild.";
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeController()) << "Starting firmware update for NXP controller";
|
||||
qCDebug(dcZigbeeController()) << "Firmware file:" << m_availableFirmwareFileName;
|
||||
qCDebug(dcZigbeeController()) << "Firmware version:" << m_availableFirmwareVersion;
|
||||
m_updateProcess->start();
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 FIRMWAREUPDATEHANDLERNXP_H
|
||||
#define FIRMWAREUPDATEHANDLERNXP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
class FirmwareUpdateHandlerNxp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FirmwareUpdateHandlerNxp(QObject *parent = nullptr);
|
||||
FirmwareUpdateHandlerNxp(const QFileInfo &updateProviderConfgigurationFileInfo, QObject *parent = nullptr);
|
||||
|
||||
bool updateRunning() const;
|
||||
bool isValid() const;
|
||||
|
||||
QString updateBinary() const;
|
||||
QString availableFirmwareFileName() const;
|
||||
QString availableFirmwareVersion() const;
|
||||
|
||||
void startUpdate();
|
||||
|
||||
signals:
|
||||
void updateRunningChanged(bool updateRunning);
|
||||
void updateFinished(bool success);
|
||||
|
||||
private:
|
||||
QFileInfo m_updateProviderConfgigurationFileInfo;
|
||||
bool m_valid = false;
|
||||
QProcess *m_updateProcess = nullptr;
|
||||
|
||||
QString m_updateBinary;
|
||||
QString m_updateReleaseFilePath;
|
||||
QString m_availableFirmwareFileName;
|
||||
QString m_availableFirmwareVersion;
|
||||
|
||||
};
|
||||
|
||||
#endif // FIRMWAREUPDATEHANDLERNXP_H
|
||||
|
|
@ -298,6 +298,7 @@ void ZigbeeInterfaceNxp::disable()
|
|||
|
||||
delete m_serialPort;
|
||||
m_serialPort = nullptr;
|
||||
|
||||
qCDebug(dcZigbeeInterface()) << "Interface disabled.";
|
||||
setAvailable(false);
|
||||
qCDebug(dcZigbeeInterface()) << "Interface disabled";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeeinterfacenxpreply.h"
|
||||
|
||||
ZigbeeNetworkRequest ZigbeeInterfaceNxpReply::networkRequest() const
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEEINTERFACENXPREPLY_H
|
||||
#define ZIGBEEINTERFACENXPREPLY_H
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,31 @@
|
|||
#include "zigbeebridgecontrollernxp.h"
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeebridgecontrollernxp.h"
|
||||
#include "loggingcategory.h"
|
||||
#include "zigbeeutils.h"
|
||||
|
||||
|
|
@ -205,6 +232,40 @@ ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestSendRequest(const Zig
|
|||
return interfaceReply;
|
||||
}
|
||||
|
||||
bool ZigbeeBridgeControllerNxp::updateAvailable(const QString ¤tVersion)
|
||||
{
|
||||
if (!m_firmwareUpdateHandler)
|
||||
return false;
|
||||
|
||||
if (m_firmwareUpdateHandler->availableFirmwareVersion() != currentVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ZigbeeBridgeControllerNxp::updateFirmwareVersion() const
|
||||
{
|
||||
if (!m_firmwareUpdateHandler)
|
||||
return QString();
|
||||
|
||||
return m_firmwareUpdateHandler->availableFirmwareVersion();
|
||||
}
|
||||
|
||||
void ZigbeeBridgeControllerNxp::startFirmwareUpdate()
|
||||
{
|
||||
if (!m_firmwareUpdateHandler)
|
||||
return;
|
||||
|
||||
m_updateRunning = true;
|
||||
emit updateRunningChanged(m_updateRunning);
|
||||
|
||||
qCDebug(dcZigbeeController()) << "Disable UART interface for update...";
|
||||
m_interface->disable();
|
||||
|
||||
m_firmwareUpdateHandler->startUpdate();
|
||||
}
|
||||
|
||||
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command command, quint8 sequenceNumber, const QString &requestName, const QByteArray &requestData, QObject *parent)
|
||||
{
|
||||
// Create the reply
|
||||
|
|
@ -346,6 +407,44 @@ ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestEnqueueSendDataIeeeAd
|
|||
return createReply(Nxp::CommandSendApsDataRequest, m_sequenceNumber, "Request send ASP data request to IEEE address", message, this);
|
||||
}
|
||||
|
||||
void ZigbeeBridgeControllerNxp::initializeUpdateProvider()
|
||||
{
|
||||
QFileInfo updateProviderConfigurationFileInfo = QFileInfo(m_settingsDirectory.canonicalPath() + QDir::separator() + "zigbee-update-provider-nxp.conf");
|
||||
if (!updateProviderConfigurationFileInfo.exists()) {
|
||||
qCDebug(dcZigbeeController()) << "No firmware update provider configured for this controller.";
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeController()) << "Found update provider configuration" << updateProviderConfigurationFileInfo.absoluteFilePath();
|
||||
m_firmwareUpdateHandler = new FirmwareUpdateHandlerNxp(updateProviderConfigurationFileInfo, this);
|
||||
if (!m_firmwareUpdateHandler->isValid()) {
|
||||
qCWarning(dcZigbeeController()) << "The firmware update provider is not valid. The firmware update is not available for this NXP zigbee controller.";
|
||||
m_firmwareUpdateHandler->deleteLater();
|
||||
m_firmwareUpdateHandler = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
connect(m_firmwareUpdateHandler, &FirmwareUpdateHandlerNxp::updateFinished, this, [this](bool success){
|
||||
if (success) {
|
||||
qCDebug(dcZigbeeController()) << "Update finished successfully. Reenable controller";
|
||||
enable(m_serialPort, m_baudrate);
|
||||
m_updateRunning = false;
|
||||
emit updateRunningChanged(m_updateRunning);
|
||||
} else {
|
||||
qCWarning(dcZigbeeController()) << "Update finished with errors. Can not continue.";
|
||||
m_updateRunning = false;
|
||||
emit updateRunningChanged(m_updateRunning);
|
||||
|
||||
// Fixme: check if we should to retry
|
||||
disable();
|
||||
}
|
||||
});
|
||||
|
||||
qCDebug(dcZigbeeController()) << "The firmware update provider is valid. The firmware of this NXP controller can be updated.";
|
||||
m_canUpdate = true;
|
||||
emit canUpdateChanged(m_canUpdate);
|
||||
}
|
||||
|
||||
void ZigbeeBridgeControllerNxp::onInterfaceAvailableChanged(bool available)
|
||||
{
|
||||
qCDebug(dcZigbeeController()) << "Interface available changed" << available;
|
||||
|
|
@ -501,6 +600,8 @@ void ZigbeeBridgeControllerNxp::sendNextRequest()
|
|||
|
||||
bool ZigbeeBridgeControllerNxp::enable(const QString &serialPort, qint32 baudrate)
|
||||
{
|
||||
m_serialPort = serialPort;
|
||||
m_baudrate = baudrate;
|
||||
return m_interface->enable(serialPort, baudrate);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEEBRIDGECONTROLLERNXP_H
|
||||
#define ZIGBEEBRIDGECONTROLLERNXP_H
|
||||
|
||||
|
|
@ -11,6 +38,7 @@
|
|||
#include "zigbeenetworkkey.h"
|
||||
#include "zigbeenetworkrequest.h"
|
||||
#include "zigbeebridgecontroller.h"
|
||||
#include "firmwareupdatehandlernxp.h"
|
||||
#include "interface/zigbeeinterfacenxp.h"
|
||||
#include "interface/zigbeeinterfacenxpreply.h"
|
||||
|
||||
|
|
@ -55,6 +83,9 @@ public:
|
|||
// APS
|
||||
ZigbeeInterfaceNxpReply *requestSendRequest(const ZigbeeNetworkRequest &request);
|
||||
|
||||
bool updateAvailable(const QString ¤tVersion) override;
|
||||
QString updateFirmwareVersion() const override;
|
||||
void startFirmwareUpdate() override;
|
||||
|
||||
signals:
|
||||
void controllerStateChanged(ControllerState controllerState);
|
||||
|
|
@ -62,6 +93,10 @@ signals:
|
|||
|
||||
private:
|
||||
ZigbeeInterfaceNxp *m_interface = nullptr;
|
||||
FirmwareUpdateHandlerNxp *m_firmwareUpdateHandler = nullptr;
|
||||
QString m_serialPort;
|
||||
qint32 m_baudrate;
|
||||
|
||||
ControllerState m_controllerState = ControllerStateNotRunning;
|
||||
quint8 m_sequenceNumber = 0;
|
||||
|
||||
|
|
@ -75,6 +110,8 @@ private:
|
|||
ZigbeeInterfaceNxpReply *requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius = 0);
|
||||
ZigbeeInterfaceNxpReply *requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, quint16 profileId, quint16 clusterId, quint8 sourceEndpoint, const QByteArray &asdu, Zigbee::ZigbeeTxOptions txOptions, quint8 radius = 0);
|
||||
|
||||
protected:
|
||||
void initializeUpdateProvider() override;
|
||||
|
||||
private slots:
|
||||
void onInterfaceAvailableChanged(bool available);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeenetworknxp.h"
|
||||
#include "loggingcategory.h"
|
||||
#include "zigbeeutils.h"
|
||||
|
|
@ -13,6 +40,20 @@ ZigbeeNetworkNxp::ZigbeeNetworkNxp(QObject *parent) :
|
|||
connect(m_controller, &ZigbeeBridgeControllerNxp::controllerStateChanged, this, &ZigbeeNetworkNxp::onControllerStateChanged);
|
||||
connect(m_controller, &ZigbeeBridgeControllerNxp::apsDataConfirmReceived, this, &ZigbeeNetworkNxp::onApsDataConfirmReceived);
|
||||
connect(m_controller, &ZigbeeBridgeControllerNxp::apsDataIndicationReceived, this, &ZigbeeNetworkNxp::onApsDataIndicationReceived);
|
||||
connect(m_controller, &ZigbeeBridgeControllerNxp::canUpdateChanged, this, [](bool canUpdate){
|
||||
if (canUpdate) {
|
||||
qCDebug(dcZigbeeNetwork()) << "The controller of this network can be updated.";
|
||||
} else {
|
||||
qCDebug(dcZigbeeNetwork()) << "The controller of this network can not be updated.";
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_controller, &ZigbeeBridgeControllerNxp::updateRunningChanged, this, [this](bool updateRunning){
|
||||
if (updateRunning) {
|
||||
qCDebug(dcZigbeeNetwork()) << "The controller is performing an update.";
|
||||
setState(StateUpdating);
|
||||
}
|
||||
});
|
||||
|
||||
m_permitJoinRefreshTimer = new QTimer(this);
|
||||
m_permitJoinRefreshTimer->setInterval(250 * 1000);
|
||||
|
|
@ -97,6 +138,64 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::setPermitJoin(quint16 shortAddress, quint8
|
|||
return sendRequest(request);
|
||||
}
|
||||
|
||||
bool ZigbeeNetworkNxp::processVersionReply(ZigbeeInterfaceNxpReply *reply)
|
||||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Version reply finished" << reply->status();
|
||||
|
||||
if (reply->timendOut()) {
|
||||
m_reconnectCounter++;
|
||||
if (m_reconnectCounter >= 3) {
|
||||
if (m_controller->canUpdate()) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Unable to get controller version.";
|
||||
qCDebug(dcZigbeeNetwork()) << "Firmware update provider available. Try to flash the firmware, maybe that fixes the problem.";
|
||||
if (!m_controller->updateRunning()) {
|
||||
clearSettings();
|
||||
qCDebug(dcZigbeeNetwork()) << "Starting firmware update...";
|
||||
m_controller->startFirmwareUpdate();
|
||||
} else {
|
||||
qCWarning(dcZigbeeNetwork()) << "There is already an update running...";
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
qCDebug(dcZigbeeNetwork()) << "Unable to get controller version. There is no firmware upgrade available. Giving up.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
qCWarning(dcZigbeeNetwork()) << "Failed to read firmware version. Retry" << m_reconnectCounter << "/ 3";
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
||||
processVersionReply(reply);
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray payload = reply->responseData();
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint8 major = 0; quint8 minor = 0; quint8 patch = 0; quint16 sdkVersion = 0;
|
||||
stream >> major >> minor >> patch >> sdkVersion;
|
||||
|
||||
QString version = QString("%1.%2.%3").arg(major).arg(minor).arg(patch);
|
||||
QString versionString = QString("%1 - %2").arg(version).arg(sdkVersion);
|
||||
qCDebug(dcZigbeeNetwork()) << "Controller version" << versionString;
|
||||
m_controller->setFirmwareVersion(versionString);
|
||||
|
||||
if (m_controller->canUpdate()) {
|
||||
if (m_controller->updateAvailable(version)) {
|
||||
qCDebug(dcZigbeeNetwork()) << "There is an update available for the this zigbee controller:" << version << "-->" << m_controller->updateFirmwareVersion();
|
||||
qCDebug(dcZigbeeNetwork()) << "Starting firmware update...";
|
||||
m_controller->startFirmwareUpdate();
|
||||
return false;
|
||||
} else {
|
||||
qCDebug(dcZigbeeNetwork()) << "The current firmware is up to date.";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkNxp::handleZigbeeDeviceProfileIndication(const Zigbee::ApsdeDataIndication &indication)
|
||||
{
|
||||
// Check if this is a device announcement
|
||||
|
|
@ -150,12 +249,15 @@ void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available)
|
|||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more");
|
||||
if (available) {
|
||||
m_reconnectCounter = 0;
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
||||
// Retry or firmware upgrade if available
|
||||
if (!processVersionReply(reply))
|
||||
return;
|
||||
|
||||
m_controller->refreshControllerState();
|
||||
// Get network state, depending on the controller state
|
||||
|
||||
//reset();
|
||||
//factoryResetNetwork();
|
||||
m_controller->refreshControllerState();
|
||||
});
|
||||
} else {
|
||||
setState(StateOffline);
|
||||
}
|
||||
|
|
@ -167,19 +269,14 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||
switch (controllerState) {
|
||||
case ZigbeeBridgeControllerNxp::ControllerStateRunning: {
|
||||
setState(StateStarting);
|
||||
m_reconnectCounter = 0;
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Request controller version";
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
||||
qCDebug(dcZigbeeNetwork()) << "Version reply finished" << reply->status();
|
||||
QByteArray payload = reply->responseData();
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint8 major = 0; quint8 minor = 0; quint8 patch = 0; quint16 sdkVersion = 0;
|
||||
stream >> major >> minor >> patch >> sdkVersion;
|
||||
|
||||
QString versionString = QString ("%1.%2.%3 - %4").arg(major).arg(minor).arg(patch).arg(sdkVersion);
|
||||
qCDebug(dcZigbeeNetwork()) << "Controller version" << versionString;
|
||||
m_controller->setFirmwareVersion(versionString);
|
||||
// Retry or firmware upgrade if available
|
||||
if (!processVersionReply(reply))
|
||||
return;
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Get the current network state";
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestNetworkState();
|
||||
|
|
@ -201,7 +298,6 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||
setPanId(panId);
|
||||
setChannel(channel);
|
||||
|
||||
|
||||
// Initialize the coordinator node if not already done.
|
||||
|
||||
if (m_coordinatorNode) {
|
||||
|
|
@ -242,8 +338,9 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|||
qCDebug(dcZigbeeNetwork()) << "Request controller version";
|
||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
||||
qCDebug(dcZigbeeNetwork()) << "Version reply finished" << reply->status();
|
||||
//FIXME: error handling
|
||||
// Retry or firmware upgrade if available
|
||||
if (!processVersionReply(reply))
|
||||
return;
|
||||
|
||||
QByteArray payload = reply->responseData();
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEENETWORKNXP_H
|
||||
#define ZIGBEENETWORKNXP_H
|
||||
|
||||
|
|
@ -25,9 +52,12 @@ private:
|
|||
ZigbeeBridgeControllerNxp *m_controller = nullptr;
|
||||
bool m_networkRunning = false;
|
||||
QHash<quint8, ZigbeeNetworkReply *> m_pendingReplies;
|
||||
int m_reconnectCounter = 0;
|
||||
|
||||
QTimer *m_permitJoinRefreshTimer = nullptr;
|
||||
|
||||
bool processVersionReply(ZigbeeInterfaceNxpReply *reply);
|
||||
|
||||
// ZDO
|
||||
void handleZigbeeDeviceProfileIndication(const Zigbee::ApsdeDataIndication &indication);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ SOURCES += \
|
|||
backends/deconz/interface/zigbeeinterfacedeconzreply.cpp \
|
||||
backends/deconz/zigbeebridgecontrollerdeconz.cpp \
|
||||
backends/deconz/zigbeenetworkdeconz.cpp \
|
||||
backends/nxp/firmwareupdatehandlernxp.cpp \
|
||||
backends/nxp/interface/zigbeeinterfacenxp.cpp \
|
||||
backends/nxp/interface/zigbeeinterfacenxpreply.cpp \
|
||||
backends/nxp/zigbeebridgecontrollernxp.cpp \
|
||||
|
|
@ -63,6 +64,7 @@ HEADERS += \
|
|||
backends/deconz/interface/zigbeeinterfacedeconzreply.h \
|
||||
backends/deconz/zigbeebridgecontrollerdeconz.h \
|
||||
backends/deconz/zigbeenetworkdeconz.h \
|
||||
backends/nxp/firmwareupdatehandlernxp.h \
|
||||
backends/nxp/interface/nxp.h \
|
||||
backends/nxp/interface/zigbeeinterfacenxp.h \
|
||||
backends/nxp/interface/zigbeeinterfacenxpreply.h \
|
||||
|
|
|
|||
|
|
@ -43,6 +43,43 @@ bool ZigbeeBridgeController::available() const
|
|||
return m_available;
|
||||
}
|
||||
|
||||
bool ZigbeeBridgeController::canUpdate() const
|
||||
{
|
||||
return m_canUpdate;
|
||||
}
|
||||
|
||||
bool ZigbeeBridgeController::updateRunning() const
|
||||
{
|
||||
return m_updateRunning;
|
||||
}
|
||||
|
||||
bool ZigbeeBridgeController::updateAvailable(const QString ¤tVersion)
|
||||
{
|
||||
Q_UNUSED(currentVersion)
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ZigbeeBridgeController::updateFirmwareVersion() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ZigbeeBridgeController::startFirmwareUpdate()
|
||||
{
|
||||
qCWarning(dcZigbeeController()) << "Cannot start firmware update. The feature is not implemented for this controller.";
|
||||
}
|
||||
|
||||
void ZigbeeBridgeController::setSettingsDirectory(const QDir &settingsDirectory)
|
||||
{
|
||||
qCDebug(dcZigbeeController()) << "Using settings directory" << settingsDirectory.canonicalPath();
|
||||
m_settingsDirectory = settingsDirectory;
|
||||
|
||||
// Check if we have an update provider for the controller, if so,
|
||||
// we can perform an automatic updates
|
||||
|
||||
initializeUpdateProvider();
|
||||
}
|
||||
|
||||
void ZigbeeBridgeController::setAvailable(bool available)
|
||||
{
|
||||
if (m_available == available)
|
||||
|
|
@ -62,3 +99,8 @@ void ZigbeeBridgeController::setFirmwareVersion(const QString &firmwareVersion)
|
|||
m_firmwareVersion = firmwareVersion;
|
||||
emit firmwareVersionChanged(m_firmwareVersion);
|
||||
}
|
||||
|
||||
void ZigbeeBridgeController::initializeUpdateProvider()
|
||||
{
|
||||
qCDebug(dcZigbeeController()) << "No firmware update provider configured for this controller.";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@
|
|||
#ifndef ZIGBEEBRIDGECONTROLLER_H
|
||||
#define ZIGBEEBRIDGECONTROLLER_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QSerialPort>
|
||||
|
||||
#include "zigbee.h"
|
||||
|
||||
Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
|
||||
|
|
@ -37,6 +39,8 @@ Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
|
|||
class ZigbeeBridgeController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ZigbeeNetwork;
|
||||
|
||||
public:
|
||||
explicit ZigbeeBridgeController(QObject *parent = nullptr);
|
||||
~ZigbeeBridgeController() = default;
|
||||
|
|
@ -44,17 +48,35 @@ public:
|
|||
QString firmwareVersion() const;
|
||||
bool available() const;
|
||||
|
||||
bool canUpdate() const;
|
||||
bool updateRunning() const;
|
||||
|
||||
virtual bool updateAvailable(const QString ¤tVersion);
|
||||
virtual QString updateFirmwareVersion() const;
|
||||
virtual void startFirmwareUpdate();
|
||||
|
||||
protected:
|
||||
QString m_firmwareVersion;
|
||||
bool m_available = false;
|
||||
bool m_canUpdate = false;
|
||||
bool m_updateRunning = false;
|
||||
QDir m_settingsDirectory;
|
||||
|
||||
void setAvailable(bool available);
|
||||
void setFirmwareVersion(const QString &firmwareVersion);
|
||||
|
||||
virtual void initializeUpdateProvider();
|
||||
|
||||
private:
|
||||
void setSettingsDirectory(const QDir &settingsDirectory);
|
||||
|
||||
signals:
|
||||
void availableChanged(bool available);
|
||||
void firmwareVersionChanged(const QString &firmwareVersion);
|
||||
void canUpdateChanged(bool canUpdate);
|
||||
void updateRunningChanged(bool updateRunning);
|
||||
|
||||
// APS notifications
|
||||
void apsDataConfirmReceived(const Zigbee::ApsdeDataConfirm &confirm);
|
||||
void apsDataIndicationReceived(const Zigbee::ApsdeDataIndication &indication);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ QString ZigbeeNetwork::settingsFilenName() const
|
|||
|
||||
void ZigbeeNetwork::setSettingsFileName(const QString &settingsFileName)
|
||||
{
|
||||
if (m_settingsFileName == settingsFileName)
|
||||
return;
|
||||
|
||||
m_settingsFileName = settingsFileName;
|
||||
emit settingsFileNameChanged(m_settingsFileName);
|
||||
|
||||
m_settingsDirectory = QFileInfo(m_settingsFileName).canonicalPath();
|
||||
bridgeController()->setSettingsDirectory(m_settingsDirectory);
|
||||
}
|
||||
|
||||
QString ZigbeeNetwork::serialPortName() const
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#ifndef ZIGBEENETWORK_H
|
||||
#define ZIGBEENETWORK_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ public:
|
|||
StateUninitialized,
|
||||
StateOffline,
|
||||
StateStarting,
|
||||
StateUpdating,
|
||||
StateRunning,
|
||||
StateStopping
|
||||
};
|
||||
|
|
@ -134,6 +136,7 @@ private:
|
|||
|
||||
// Network storage
|
||||
QString m_settingsFileName = "/etc/nymea/nymea-zigbee.conf";
|
||||
QDir m_settingsDirectory;
|
||||
QList<ZigbeeNode *> m_nodes;
|
||||
QList<ZigbeeNode *> m_uninitializedNodes;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue