Add button mode
This commit is contained in:
parent
1a369e1845
commit
09c782e3ec
72
README.md
72
README.md
@ -7,11 +7,15 @@ if the system is currently not connected to any network. Once the system is conn
|
||||
|
||||
First you have to install build dependencies:
|
||||
|
||||
> Note: the libnymea-networkmanager-dev package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built
|
||||
> Note: the `libnymea-networkmanager-dev` package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built
|
||||
and installed from [source](https://github.com/nymea/libnymea-networkmanager).
|
||||
|
||||
|
||||
> Note: the `libnymea-gpio-dev` package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built
|
||||
and installed from [source](https://github.com/nymea/nymea-gpio).
|
||||
|
||||
$ sudo apt update
|
||||
$ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev libnymea-networkmanager-dev git
|
||||
$ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev libnymea-networkmanager-dev libnymea-gpio-dev git
|
||||
|
||||
Clone the source code and change into the source directory
|
||||
|
||||
@ -63,45 +67,41 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with
|
||||
# Command line parameters
|
||||
|
||||
$ nymea-networkmanager --help
|
||||
Usage:nymea-networkmanager [options]
|
||||
Usage: ./nymea-networkmanager [options]
|
||||
|
||||
This daemon allows to configure a wifi network using a bluetooth low energy connection.
|
||||
|
||||
Copyright © 2018 - 2019 Simon Stürz <simon.stuerz@nymea.io>
|
||||
Copyright © 2018-2019 Simon Stürz <simon.stuerz@nymea.io>
|
||||
|
||||
Modes:
|
||||
- offline This mode starts the bluetooth server once the device is offline
|
||||
and not connected to any LAN network.
|
||||
- once This mode starts the bluetooth server only if no network configuration exists.
|
||||
Once a network connection exists the server will never start again.
|
||||
- button This mode enables the bluetooth server when a GPIO button has been pressed for
|
||||
the configured timeout periode.
|
||||
- always This mode enables the bluetooth server as long the application is running.
|
||||
- start This mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.
|
||||
|
||||
|
||||
|
||||
Options:
|
||||
-h, --help Displays this help.
|
||||
-v, --version Displays version information.
|
||||
-d, --debug Enable more debug output.
|
||||
-a, --advertise-name <NAME> The name of the bluetooth
|
||||
server. Default "BT WLAN setup".
|
||||
-p, --platform-name <NAME> The name of the platform this
|
||||
daemon is running. Default
|
||||
"nymea-box".
|
||||
-t, --timeout <SECONDS> The timeout of the bluetooth
|
||||
server. Minimum value is 10.
|
||||
Default "60".
|
||||
-m, --mode <offline | once | always | start> Run the daemon in a specific
|
||||
mode. Default is "offline".
|
||||
- offline: this mode starts the
|
||||
bluetooth server once the device
|
||||
is offline and not connected to
|
||||
any LAN network.
|
||||
- once: this mode starts the
|
||||
bluetooth server only if no
|
||||
network configuration exists.
|
||||
Once a network connection exists
|
||||
the server will never start
|
||||
again.
|
||||
- always: this mode enables the
|
||||
bluetooth server as long the
|
||||
application is running.
|
||||
- start: this mode starts the
|
||||
bluetooth server for 3 minutes
|
||||
on start and shuts down after a
|
||||
connection.
|
||||
|
||||
|
||||
-h, --help Displays this help.
|
||||
-v, --version Displays version information.
|
||||
-d, --debug Enable more debug output.
|
||||
-a, --advertise-name <NAME> The name of the bluetooth server. Default "BT
|
||||
WLAN setup".
|
||||
-p, --platform-name <NAME> The name of the platform this daemon is running.
|
||||
Default "nymea-box".
|
||||
-g, --gpio <GPIO> The GPIO sysfs number for the button GPIO. This
|
||||
parameter is only needed for the "button" mode.
|
||||
-t, --timeout <SECONDS> The timeout of the bluetooth server. Minimum
|
||||
value is 10. Default "60".
|
||||
-m, --mode <MODE> Run the daemon in a specific mode (offline,
|
||||
once, always, button, start). Default is
|
||||
"offline".
|
||||
|
||||
|
||||
|
||||
# Bluetooth GATT profile
|
||||
-------------------------------------------
|
||||
|
||||
@ -3,3 +3,4 @@ Mode=offline
|
||||
Timeout=60
|
||||
AdvertiseName=BT WLAN setup
|
||||
PlatformName=nymea-box
|
||||
ButtonGpio=14
|
||||
|
||||
@ -62,7 +62,7 @@ Core::Mode Core::mode() const
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void Core::setMode(const Core::Mode &mode)
|
||||
void Core::setMode(Mode mode)
|
||||
{
|
||||
m_mode = mode;
|
||||
}
|
||||
@ -92,11 +92,21 @@ int Core::advertisingTimeout() const
|
||||
return m_advertisingTimeout;
|
||||
}
|
||||
|
||||
void Core::setAdvertisingTimeout(const int advertisingTimeout)
|
||||
void Core::setAdvertisingTimeout(int advertisingTimeout)
|
||||
{
|
||||
m_advertisingTimeout = advertisingTimeout;
|
||||
}
|
||||
|
||||
int Core::buttonGpio() const
|
||||
{
|
||||
return m_buttonGpio;
|
||||
}
|
||||
|
||||
void Core::setButtonGpio(int buttonGpio)
|
||||
{
|
||||
m_buttonGpio = buttonGpio;
|
||||
}
|
||||
|
||||
void Core::run()
|
||||
{
|
||||
// Start the networkmanager
|
||||
@ -243,6 +253,17 @@ void Core::postRun()
|
||||
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||
}
|
||||
break;
|
||||
case ModeButton:
|
||||
// Enable button
|
||||
m_button = new GpioButton(m_buttonGpio, this);
|
||||
m_button->setLongPressedTimeout(2000);
|
||||
connect(m_button, &GpioButton::longPressed, this, &Core::onButtonLongPressed);
|
||||
if (!m_button->enable()) {
|
||||
qCCritical(dcApplication()) << "Could not not enable GPIO button for" << m_buttonGpio;
|
||||
m_button->deleteLater();
|
||||
m_button = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,6 +309,8 @@ void Core::onBluetoothServerRunningChanged(bool running)
|
||||
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||
}
|
||||
break;
|
||||
case ModeButton:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -336,6 +359,8 @@ void Core::onNetworkManagerAvailableChanged(bool available)
|
||||
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||
}
|
||||
break;
|
||||
case ModeButton:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,6 +369,11 @@ void Core::onNetworkManagerStateChanged(NetworkManager::NetworkManagerState stat
|
||||
evaluateNetworkManagerState(state);
|
||||
}
|
||||
|
||||
void Core::onButtonLongPressed()
|
||||
{
|
||||
startService();
|
||||
}
|
||||
|
||||
void Core::onNymeaServiceAvailableChanged(bool available)
|
||||
{
|
||||
if (available)
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "nymeadservice.h"
|
||||
#include "nymea-gpio/gpiobutton.h"
|
||||
#include "bluetooth/bluetoothserver.h"
|
||||
#include "nymea-networkmanager/networkmanager.h"
|
||||
#include "nymea-networkmanager/bluetooth/bluetoothserver.h"
|
||||
@ -38,7 +39,8 @@ public:
|
||||
ModeAlways,
|
||||
ModeOffline,
|
||||
ModeOnce,
|
||||
ModeStart
|
||||
ModeStart,
|
||||
ModeButton
|
||||
};
|
||||
Q_ENUM(Mode)
|
||||
|
||||
@ -50,7 +52,7 @@ public:
|
||||
NymeadService *nymeaService() const;
|
||||
|
||||
Mode mode() const;
|
||||
void setMode(const Mode &mode);
|
||||
void setMode(Mode mode);
|
||||
|
||||
QString advertiseName() const;
|
||||
void setAdvertiseName(const QString &name);
|
||||
@ -59,7 +61,10 @@ public:
|
||||
void setPlatformName(const QString &name);
|
||||
|
||||
int advertisingTimeout() const;
|
||||
void setAdvertisingTimeout(const int advertisingTimeout);
|
||||
void setAdvertisingTimeout(int advertisingTimeout);
|
||||
|
||||
int buttonGpio() const;
|
||||
void setButtonGpio(int buttonGpio);
|
||||
|
||||
void run();
|
||||
|
||||
@ -73,6 +78,7 @@ private:
|
||||
BluetoothServer *m_bluetoothServer = nullptr;
|
||||
NymeadService *m_nymeaService = nullptr;
|
||||
WirelessNetworkDevice *m_wirelessDevice = nullptr;
|
||||
GpioButton *m_button = nullptr;
|
||||
|
||||
QTimer *m_advertisingTimer = nullptr;
|
||||
|
||||
@ -81,6 +87,7 @@ private:
|
||||
QString m_platformName;
|
||||
int m_advertisingTimeout = 60;
|
||||
bool m_initRunning = true;
|
||||
int m_buttonGpio = -1;
|
||||
|
||||
void evaluateNetworkManagerState(NetworkManager::NetworkManagerState state);
|
||||
|
||||
@ -98,6 +105,8 @@ private slots:
|
||||
void onNetworkManagerAvailableChanged(bool available);
|
||||
void onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state);
|
||||
|
||||
void onButtonLongPressed();
|
||||
|
||||
void onNymeaServiceAvailableChanged(bool available);
|
||||
|
||||
};
|
||||
|
||||
@ -84,6 +84,7 @@ int main(int argc, char *argv[])
|
||||
// Default configuration:
|
||||
Core::Mode mode = Core::ModeOffline;
|
||||
int timeout = 60;
|
||||
int buttonGpio = -1;
|
||||
QString advertiseName = "BT WLAN setup";
|
||||
QString platformName = "nymea-box";
|
||||
|
||||
@ -96,8 +97,17 @@ int main(int argc, char *argv[])
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection." \
|
||||
"\n\nCopyright %1 2018-2019 Simon Stürz <simon.stuerz@nymea.io>").arg(QChar(0xA9)));
|
||||
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection.\n\n"
|
||||
"Copyright %1 2018-2019 Simon Stürz <simon.stuerz@nymea.io>\n\n"
|
||||
"Modes: \n"
|
||||
" - offline This mode starts the bluetooth server once the device is offline\n"
|
||||
" and not connected to any LAN network.\n"
|
||||
" - once This mode starts the bluetooth server only if no network configuration exists.\n"
|
||||
" Once a network connection exists the server will never start again.\n"
|
||||
" - button This mode enables the bluetooth server when a GPIO button has been pressed for\n"
|
||||
" the configured timeout periode.\n"
|
||||
" - always This mode enables the bluetooth server as long the application is running.\n"
|
||||
" - start This mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.\n\n").arg(QChar(0xA9)));
|
||||
|
||||
QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output.");
|
||||
parser.addOption(debugOption);
|
||||
@ -110,15 +120,15 @@ int main(int argc, char *argv[])
|
||||
platformNameOption.setDefaultValue(platformName);
|
||||
parser.addOption(platformNameOption);
|
||||
|
||||
QCommandLineOption gpioOption(QStringList() << "g" << "gpio", QString("The GPIO sysfs number for the button GPIO. This parameter is only needed for the \"button\" mode."), "GPIO");
|
||||
platformNameOption.setDefaultValue("-1");
|
||||
parser.addOption(gpioOption);
|
||||
|
||||
QCommandLineOption timeoutOption(QStringList() << "t" << "timeout", QString("The timeout of the bluetooth server. Minimum value is 10. Default \"%1\".").arg(timeout), "SECONDS");
|
||||
timeoutOption.setDefaultValue(QString::number(timeout));
|
||||
parser.addOption(timeoutOption);
|
||||
|
||||
QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode. Default is \"offline\".\n\n" \
|
||||
"- offline: this mode starts the bluetooth server once the device is offline and not connected to any LAN network.\n\n" \
|
||||
"- once: this mode starts the bluetooth server only if no network configuration exists. Once a network connection exists the server will never start again.\n\n" \
|
||||
"- always: this mode enables the bluetooth server as long the application is running.\n\n" \
|
||||
"- start: this mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.\n\n", "offline | once | always | start");
|
||||
QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode (offline, once, always, button, start). Default is \"offline\".", "MODE");
|
||||
parser.addOption(modeOption);
|
||||
|
||||
parser.process(application);
|
||||
@ -132,6 +142,7 @@ int main(int argc, char *argv[])
|
||||
QLoggingCategory::installFilter(loggingCategoryFilter);
|
||||
|
||||
bool timeoutValueOk = true;
|
||||
bool gpioValueOk = true;
|
||||
|
||||
// Now read the cofig file, overriding defaults
|
||||
QStringList configLocations;
|
||||
@ -152,10 +163,15 @@ int main(int argc, char *argv[])
|
||||
mode = Core::ModeStart;
|
||||
} else if (settings.value("Mode").toString().toLower() == "once") {
|
||||
mode = Core::ModeOnce;
|
||||
} else if (settings.value("Mode").toString().toLower() == "button") {
|
||||
mode = Core::ModeButton;
|
||||
} else {
|
||||
qCWarning(dcApplication()).noquote() << QString("The config file's mode \"%1\" does not match the allowed modes.").arg(settings.value("Mode").toString());
|
||||
}
|
||||
}
|
||||
if (settings.contains("ButtonGpio")) {
|
||||
buttonGpio = settings.value("ButtonGpio", -1).toInt(&gpioValueOk);
|
||||
}
|
||||
if (settings.contains("Timeout")) {
|
||||
timeout = settings.value("Timeout").toInt(&timeoutValueOk);
|
||||
}
|
||||
@ -179,7 +195,10 @@ int main(int argc, char *argv[])
|
||||
mode = Core::ModeStart;
|
||||
} else if (parser.value(modeOption).toLower() == "once") {
|
||||
mode = Core::ModeOnce;
|
||||
} else {
|
||||
} else if (parser.value(modeOption).toLower() == "button") {
|
||||
mode = Core::ModeButton;
|
||||
|
||||
} else {
|
||||
qCWarning(dcApplication()).noquote() << QString("The given mode \"%1\" does not match the allowed modes.").arg(parser.value(modeOption));
|
||||
parser.showHelp(1);
|
||||
}
|
||||
@ -193,15 +212,27 @@ int main(int argc, char *argv[])
|
||||
if (parser.isSet(timeoutOption)) {
|
||||
timeout = parser.value(timeoutOption).toInt(&timeoutValueOk);
|
||||
}
|
||||
if (parser.isSet(gpioOption)) {
|
||||
buttonGpio = parser.value(gpioOption).toInt(&gpioValueOk);
|
||||
}
|
||||
|
||||
// All parsed. Validate input:
|
||||
if (!timeoutValueOk) {
|
||||
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". Please pass an integer >= 10").arg(parser.value(timeoutOption));
|
||||
parser.showHelp(1);
|
||||
return(1);
|
||||
}
|
||||
if (!gpioValueOk) {
|
||||
qCCritical(dcApplication()) << QString("Invalid GPIO number value passed: \"%1\". Please pass an integer > 0").arg(parser.value(gpioOption));
|
||||
return(1);
|
||||
}
|
||||
if (timeout < 10) {
|
||||
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". The minimal timeout is 10 [s].").arg(parser.value(timeoutOption));
|
||||
parser.showHelp(1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mode == Core::ModeButton && buttonGpio <= 0) {
|
||||
qCCritical(dcApplication()) << "Button mode selected but no valid GPIO passed.";
|
||||
return(1);
|
||||
}
|
||||
|
||||
qCDebug(dcApplication()) << "=====================================";
|
||||
@ -211,12 +242,15 @@ int main(int argc, char *argv[])
|
||||
qCDebug(dcApplication()) << "Platform name:" << platformName;
|
||||
qCDebug(dcApplication()) << "Mode:" << mode;
|
||||
qCDebug(dcApplication()) << "Timeout:" << timeout;
|
||||
if (mode == Core::ModeButton)
|
||||
qCDebug(dcApplication()) << "Button GPIO:" << buttonGpio;
|
||||
|
||||
// Start core
|
||||
Core::instance()->setMode(mode);
|
||||
Core::instance()->setAdvertisingTimeout(timeout);
|
||||
Core::instance()->setAdvertiseName(advertiseName);
|
||||
Core::instance()->setPlatformName(platformName);
|
||||
Core::instance()->setButtonGpio(buttonGpio);
|
||||
|
||||
Core::instance()->run();
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ CONFIG += console link_pkgconfig
|
||||
CONFIG -= app_bundle
|
||||
|
||||
TEMPLATE = app
|
||||
PKGCONFIG += nymea-networkmanager
|
||||
PKGCONFIG += nymea-networkmanager nymea-gpio
|
||||
|
||||
HEADERS += \
|
||||
application.h \
|
||||
|
||||
Reference in New Issue
Block a user