diff --git a/libnymea-app-core/libnymea-app-core.h b/libnymea-app-core/libnymea-app-core.h index 876578c8..650259ce 100644 --- a/libnymea-app-core/libnymea-app-core.h +++ b/libnymea-app-core/libnymea-app-core.h @@ -36,7 +36,7 @@ #include "models/valuelogsproxymodel.h" #include "models/interfacesproxy.h" #include "configuration/basicconfiguration.h" -#include "wifisetup/networkmanagercontroler.h" +#include "wifisetup/networkmanagercontroller.h" #include "wifisetup/wirelessaccesspoint.h" #include "wifisetup/wirelessaccesspoints.h" #include "wifisetup/wirelessaccesspointsproxy.h" @@ -161,14 +161,14 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "Tag", "Get it from Tags"); qmlRegisterType(uri, 1, 0, "TagsProxyModel"); - qmlRegisterType(uri, 1, 0, "NetworkManagerControler"); + qmlRegisterType(uri, 1, 0, "NetworkManagerController"); qmlRegisterType(uri, 1, 0, "BluetoothDiscovery"); qmlRegisterUncreatableType(uri, 1, 0, "BluetoothDeviceInfo", "Can't create this in QML. Get it from the DeviceInfos."); qmlRegisterUncreatableType(uri, 1, 0, "BluetoothDeviceInfos", "Can't create this in QML. Get it from the BluetoothDiscovery."); qmlRegisterUncreatableType(uri, 1, 0, "WirelessSetupManager", "Can't create this in QML. Get it from the NetworkManagerControler."); qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the WirelessAccessPoints."); qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance."); - qmlRegisterUncreatableType(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance."); + qmlRegisterType(uri, 1, 0, "WirelessAccessPointsProxy"); qmlRegisterSingletonType(uri, 1, 0, "AWSClient", awsClientProvider); qmlRegisterUncreatableType(uri, 1, 0, "AWSDevice", "Can't create this in QML. Get it from AWSClient"); diff --git a/libnymea-app-core/libnymea-app-core.pro b/libnymea-app-core/libnymea-app-core.pro index 0a2f6509..a0a3e3a0 100644 --- a/libnymea-app-core/libnymea-app-core.pro +++ b/libnymea-app-core/libnymea-app-core.pro @@ -63,7 +63,7 @@ SOURCES += \ wifisetup/wirelessaccesspoint.cpp \ wifisetup/wirelessaccesspoints.cpp \ wifisetup/wirelesssetupmanager.cpp \ - wifisetup/networkmanagercontroler.cpp \ + wifisetup/networkmanagercontroller.cpp \ models/logsmodelng.cpp \ models/interfacesproxy.cpp \ models/tagsproxymodel.cpp \ @@ -123,7 +123,7 @@ HEADERS += \ wifisetup/wirelessaccesspoint.h \ wifisetup/wirelessaccesspoints.h \ wifisetup/wirelesssetupmanager.h \ - wifisetup/networkmanagercontroler.h \ + wifisetup/networkmanagercontroller.h \ libnymea-app-core.h \ models/logsmodelng.h \ models/interfacesproxy.h \ diff --git a/libnymea-app-core/wifisetup/bluetoothdevice.cpp b/libnymea-app-core/wifisetup/bluetoothdevice.cpp index 763be3ee..5fb49b0b 100644 --- a/libnymea-app-core/wifisetup/bluetoothdevice.cpp +++ b/libnymea-app-core/wifisetup/bluetoothdevice.cpp @@ -27,8 +27,8 @@ BluetoothDevice::BluetoothDevice(const QBluetoothDeviceInfo &deviceInfo, QObject m_deviceInfo(deviceInfo), m_connected(false) { - m_controller = new QLowEnergyController(deviceInfo, this); - m_controller->setRemoteAddressType(QLowEnergyController::PublicAddress); + m_controller = QLowEnergyController::createCentral(deviceInfo, this); +// m_controller->setRemoteAddressType(QLowEnergyController::PublicAddress); connect(m_controller, &QLowEnergyController::connected, this, &BluetoothDevice::onConnected); connect(m_controller, &QLowEnergyController::disconnected, this, &BluetoothDevice::onDisconnected); @@ -71,6 +71,11 @@ QString BluetoothDevice::statusText() const void BluetoothDevice::connectDevice() { + if (m_controller->state() != QLowEnergyController::UnconnectedState) { + qDebug() << "Controller in state:" << m_controller->state() << "Not connecting..."; + return; + } + qDebug() << "QLoweEnergyController connecting..."; m_controller->connectToDevice(); } @@ -144,6 +149,7 @@ void BluetoothDevice::onDeviceStateChanged(const QLowEnergyController::Controlle setStatusText(QString(tr("%1 disconnected.").arg(name()))); break; default: + qDebug() << "BluetoothDevice: Unhandled state entered:" << state; break; } } diff --git a/libnymea-app-core/wifisetup/bluetoothdevice.h b/libnymea-app-core/wifisetup/bluetoothdevice.h index 46773b88..43a56acc 100644 --- a/libnymea-app-core/wifisetup/bluetoothdevice.h +++ b/libnymea-app-core/wifisetup/bluetoothdevice.h @@ -37,7 +37,7 @@ class BluetoothDevice : public QObject Q_PROPERTY(QString statusText READ statusText NOTIFY statusTextChanged) public: - explicit BluetoothDevice(const QBluetoothDeviceInfo &deviceInfo, QObject *parent = 0); + explicit BluetoothDevice(const QBluetoothDeviceInfo &deviceInfo, QObject *parent = nullptr); QString name() const; QBluetoothAddress address() const; diff --git a/libnymea-app-core/wifisetup/bluetoothdeviceinfos.cpp b/libnymea-app-core/wifisetup/bluetoothdeviceinfos.cpp index 08af3b46..991311ea 100644 --- a/libnymea-app-core/wifisetup/bluetoothdeviceinfos.cpp +++ b/libnymea-app-core/wifisetup/bluetoothdeviceinfos.cpp @@ -22,6 +22,8 @@ #include "bluetoothdeviceinfos.h" +#include + BluetoothDeviceInfos::BluetoothDeviceInfos(QObject *parent) : QAbstractListModel(parent) { @@ -70,9 +72,12 @@ BluetoothDeviceInfo *BluetoothDeviceInfos::get(int index) const void BluetoothDeviceInfos::addBluetoothDeviceInfo(BluetoothDeviceInfo *deviceInfo) { + qDebug() << "Adding device" << deviceInfo->name(); + deviceInfo->setParent(this); beginInsertRows(QModelIndex(), m_deviceInfos.count(), m_deviceInfos.count()); m_deviceInfos.append(deviceInfo); endInsertRows(); + emit countChanged(); } void BluetoothDeviceInfos::clearModel() @@ -81,6 +86,7 @@ void BluetoothDeviceInfos::clearModel() qDeleteAll(m_deviceInfos); m_deviceInfos.clear(); endResetModel(); + emit countChanged(); } QHash BluetoothDeviceInfos::roleNames() const diff --git a/libnymea-app-core/wifisetup/bluetoothdeviceinfos.h b/libnymea-app-core/wifisetup/bluetoothdeviceinfos.h index 4e256cd3..6b0598f9 100644 --- a/libnymea-app-core/wifisetup/bluetoothdeviceinfos.h +++ b/libnymea-app-core/wifisetup/bluetoothdeviceinfos.h @@ -31,6 +31,7 @@ class BluetoothDeviceInfos : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: enum BluetoothDeviceInfoRole { BluetoothDeviceInfoRoleName = Qt::DisplayRole, @@ -45,12 +46,15 @@ public: int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; - Q_INVOKABLE int count() const; + int count() const; Q_INVOKABLE BluetoothDeviceInfo *get(int index) const; void addBluetoothDeviceInfo(BluetoothDeviceInfo *deviceInfo); Q_INVOKABLE void clearModel(); +signals: + void countChanged(); + protected: QHash roleNames() const; diff --git a/libnymea-app-core/wifisetup/bluetoothdiscovery.cpp b/libnymea-app-core/wifisetup/bluetoothdiscovery.cpp index b7fc0853..b37c7812 100644 --- a/libnymea-app-core/wifisetup/bluetoothdiscovery.cpp +++ b/libnymea-app-core/wifisetup/bluetoothdiscovery.cpp @@ -23,6 +23,7 @@ #include "bluetoothdiscovery.h" #include +#include #include BluetoothDiscovery::BluetoothDiscovery(QObject *parent) : @@ -35,40 +36,40 @@ BluetoothDiscovery::BluetoothDiscovery(QObject *parent) : QBluetoothLocalDevice localDevice; if (!localDevice.isValid()) { qWarning() << "BluetoothDiscovery: there is no bluetooth device available."; - setBluetoothAvailable(false); + m_bluetoothAvailable = false; return; } if (localDevice.allDevices().isEmpty()) { qWarning() << "BluetoothDiscovery: there is no bluetooth device available currently."; - setBluetoothAvailable(false); + m_bluetoothAvailable = false; return; } - setBluetoothAvailable(true); + m_bluetoothAvailable = true; // FIXME: check the device with the most capabilities and check if low energy is available QBluetoothHostInfo adapterHostInfo = localDevice.allDevices().first(); - qDebug() << "BluetoothDiscovery: using bluetooth adapter" << adapterHostInfo.name() << adapterHostInfo.address().toString(); m_localDevice = new QBluetoothLocalDevice(adapterHostInfo.address(), this); connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothDiscovery::onBluetoothHostModeChanged); onBluetoothHostModeChanged(m_localDevice->hostMode()); - m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localDevice->address(), this); #else // Note: on iOS there is no QBluetoothLocalDevice available, therefore we have to assume there is one and // start the discovery agent with the default constructor. // https://bugreports.qt.io/browse/QTBUG-65547 - setBluetoothAvailable(true); - setBluetoothEnabled(true); - m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); + m_bluetoothAvailable = true; + + // Always start with assuming BT is enabled + m_bluetoothEnabled = true; + + qDebug() << "Initializing Bluetooth"; + onBluetoothHostModeChanged(QBluetoothLocalDevice::HostConnectable); #endif - connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered); - connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished); - connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); + } bool BluetoothDiscovery::bluetoothAvailable() const @@ -78,27 +79,50 @@ bool BluetoothDiscovery::bluetoothAvailable() const bool BluetoothDiscovery::bluetoothEnabled() const { - return m_bluetoothEnabled; +#ifdef Q_OS_IOS + return m_bluetoothAvailable && m_bluetoothEnabled; +#endif + qDebug() << "bluetoothEnabled(): m_bluetoothAvailable:" << m_bluetoothAvailable; + return m_bluetoothAvailable && m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff; +} +void BluetoothDiscovery::setBluetoothEnabled(bool bluetoothEnabled) { + if (!m_bluetoothAvailable) { + return; + } + if (bluetoothEnabled) { + if (m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) { + m_localDevice->powerOn(); + } + } else { + if (m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff) { + m_localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff); + } + } } -void BluetoothDiscovery::setBluetoothEnabled(bool enabled) +bool BluetoothDiscovery::discoveryEnabled() const { - m_bluetoothEnabled = enabled; - emit bluetoothEnabledChanged(m_bluetoothEnabled); - - if (!m_localDevice) - return; - - if (enabled) { - m_localDevice->powerOn(); - } else { - m_localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff); - } + return m_discoveryEnabled; } bool BluetoothDiscovery::discovering() const { - return m_discovering; + return m_discoveryAgent && m_discoveryAgent->isActive(); +} + +void BluetoothDiscovery::setDiscoveryEnabled(bool discoveryEnabled) +{ + if (m_discoveryEnabled == discoveryEnabled) { + return; + } + m_discoveryEnabled = discoveryEnabled; + emit discoveringChanged(); + + if (m_discoveryEnabled) { + start(); + } else { + stop(); + } } BluetoothDeviceInfos *BluetoothDiscovery::deviceInfos() @@ -106,36 +130,36 @@ BluetoothDeviceInfos *BluetoothDiscovery::deviceInfos() return m_deviceInfos; } -void BluetoothDiscovery::setBluetoothAvailable(bool available) -{ - if (m_bluetoothAvailable == available) - return; - - m_bluetoothAvailable = available; - emit bluetoothAvailableChanged(m_bluetoothAvailable); -} - -void BluetoothDiscovery::setDiscovering(bool discovering) -{ - if (m_discovering == discovering) - return; - - m_discovering = discovering; - emit discoveringChanged(m_discovering); -} - void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice::HostMode &hostMode) { -// qDebug() << "BluetoothDiscovery: host mode changed" << hostMode; + qDebug() << "BluetoothDiscovery: host mode changed" << hostMode; switch (hostMode) { case QBluetoothLocalDevice::HostPoweredOff: - setBluetoothEnabled(false); - stop(); + if (m_discoveryAgent) { + stop(); + m_discoveryAgent->deleteLater(); + m_discoveryAgent = nullptr; + } m_deviceInfos->clearModel(); + emit bluetoothEnabledChanged(false); break; default: // Note: discovery works in all other modes - setBluetoothEnabled(true); + emit bluetoothEnabledChanged(hostMode != QBluetoothLocalDevice::HostPoweredOff); + if (!m_discoveryAgent) { +#ifdef Q_OS_ANDROID + m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localDevice->address(), this); +#else + m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); +#endif + connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered); + connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished); + connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothDiscovery::discoveryCancelled); + connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); + } + if (m_discoveryEnabled && !m_discoveryAgent->isActive()) { + start(); + } break; } } @@ -148,7 +172,7 @@ void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo); bool isLowEnergy = deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration; -// qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : ""); + qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : ""); if (!isLowEnergy || deviceInformation->name().isEmpty()) { delete deviceInformation; @@ -158,7 +182,7 @@ void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo // Check if we already have added this device info foreach (BluetoothDeviceInfo *di, m_deviceInfos->deviceInfos()) { if (di->address() == deviceInformation->address()) { -// qWarning() << "BluetoothDiscover: device" << deviceInformation->name() << "(" << deviceInformation->address() << ") already added"; + qWarning() << "BluetoothDiscover: device" << deviceInformation->name() << "(" << deviceInformation->address() << ") already added"; deviceInformation->deleteLater(); return; } @@ -169,47 +193,59 @@ void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo void BluetoothDiscovery::discoveryFinished() { -// qDebug() << "BluetoothDiscovery: Discovery finished"; - if (m_enabled) { + qDebug() << "BluetoothDiscovery: Discovery finished"; + if (m_discoveryEnabled) { + qDebug() << "BluetoothDiscovery: Restarting discovery"; m_discoveryAgent->start(); } } +void BluetoothDiscovery::discoveryCancelled() +{ + qDebug() << "BluetoothDiscovery: Discovery cancelled"; +} + void BluetoothDiscovery::onError(const QBluetoothDeviceDiscoveryAgent::Error &error) { qWarning() << "BluetoothDiscovery: Discovery error:" << error << m_discoveryAgent->errorString(); - setDiscovering(false); +#ifdef Q_OS_IOS + if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError) { + m_bluetoothEnabled = false; + emit bluetoothEnabledChanged(false); + onBluetoothHostModeChanged(QBluetoothLocalDevice::HostPoweredOff); + QTimer::singleShot(5000, this, [this] () { + m_bluetoothEnabled = true; + onBluetoothHostModeChanged(QBluetoothLocalDevice::HostConnectable); + }); + } +#endif + emit discoveringChanged(); } void BluetoothDiscovery::start() { - m_enabled = true; - - if (!m_discoveryAgent) - return; - - if (m_discoveryAgent->isActive()) - m_discoveryAgent->stop(); - - m_deviceInfos->clearModel(); - - if (!m_bluetoothEnabled) { + if (!m_discoveryAgent || !bluetoothEnabled()) { return; } -// qDebug() << "BluetoothDiscovery: Start discovering."; + if (m_discoveryAgent->isActive()) { + m_discoveryAgent->stop(); + } + + m_deviceInfos->clearModel(); + + qDebug() << "BluetoothDiscovery: Start discovering."; m_discoveryAgent->start(); - setDiscovering(true); + emit discoveringChanged(); } void BluetoothDiscovery::stop() { - m_enabled = false; - - if (!m_discoveryAgent) + if (!m_discoveryAgent) { return; + } -// qDebug() << "BluetoothDiscovery: Stop discovering."; + qDebug() << "BluetoothDiscovery: Stop discovering."; m_discoveryAgent->stop(); - setDiscovering(false); + emit discoveringChanged(); } diff --git a/libnymea-app-core/wifisetup/bluetoothdiscovery.h b/libnymea-app-core/wifisetup/bluetoothdiscovery.h index 756778d3..1e7a5036 100644 --- a/libnymea-app-core/wifisetup/bluetoothdiscovery.h +++ b/libnymea-app-core/wifisetup/bluetoothdiscovery.h @@ -33,51 +33,52 @@ class BluetoothDiscovery : public QObject { Q_OBJECT Q_PROPERTY(bool bluetoothAvailable READ bluetoothAvailable NOTIFY bluetoothAvailableChanged) - Q_PROPERTY(bool bluetoothEnabled READ bluetoothEnabled NOTIFY bluetoothEnabledChanged) + Q_PROPERTY(bool bluetoothEnabled READ bluetoothEnabled WRITE setBluetoothEnabled NOTIFY bluetoothEnabledChanged) + Q_PROPERTY(bool discoveryEnabled READ discoveryEnabled WRITE setDiscoveryEnabled NOTIFY discoveryEnabledChanged) Q_PROPERTY(bool discovering READ discovering NOTIFY discoveringChanged) Q_PROPERTY(BluetoothDeviceInfos *deviceInfos READ deviceInfos CONSTANT) public: - explicit BluetoothDiscovery(QObject *parent = 0); + explicit BluetoothDiscovery(QObject *parent = nullptr); bool bluetoothAvailable() const; - bool bluetoothEnabled() const; - void setBluetoothEnabled(bool enabled); + void setBluetoothEnabled(bool bluetoothEnabled); + + bool discoveryEnabled() const; + void setDiscoveryEnabled(bool discoveryEnabled); bool discovering() const; BluetoothDeviceInfos *deviceInfos(); +signals: + void bluetoothAvailableChanged(bool bluetoothAvailable); + void bluetoothEnabledChanged(bool bluetoothEnabled); + void discoveryEnabledChanged(bool discoveryEnabled); + void discoveringChanged(); + +private slots: + void onBluetoothHostModeChanged(const QBluetoothLocalDevice::HostMode &hostMode); + void deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo); + void discoveryFinished(); + void discoveryCancelled(); + void onError(const QBluetoothDeviceDiscoveryAgent::Error &error); + +private slots: + void start(); + void stop(); + private: QBluetoothLocalDevice *m_localDevice = nullptr; QBluetoothDeviceDiscoveryAgent *m_discoveryAgent = nullptr; BluetoothDeviceInfos *m_deviceInfos; - bool m_enabled = false; - bool m_discovering = false; bool m_bluetoothAvailable = false; +#ifdef Q_OS_IOS bool m_bluetoothEnabled = false; - - void setBluetoothAvailable(bool available); - void setDiscovering(bool discovering); - -signals: - void bluetoothAvailableChanged(bool bluetoothAvailable); - void bluetoothEnabledChanged(bool bluetoothEnabled); - - void discoveringChanged(bool discovering); - -private slots: - void onBluetoothHostModeChanged(const QBluetoothLocalDevice::HostMode &hostMode); - void deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo); - void discoveryFinished(); - void onError(const QBluetoothDeviceDiscoveryAgent::Error &error); - -public slots: - Q_INVOKABLE void start(); - Q_INVOKABLE void stop(); - +#endif + bool m_discoveryEnabled = false; }; #endif // BLUETOOTHDISCOVERY_H diff --git a/libnymea-app-core/wifisetup/networkmanagercontroler.cpp b/libnymea-app-core/wifisetup/networkmanagercontroller.cpp similarity index 86% rename from libnymea-app-core/wifisetup/networkmanagercontroler.cpp rename to libnymea-app-core/wifisetup/networkmanagercontroller.cpp index b7b3525e..fb36ed55 100644 --- a/libnymea-app-core/wifisetup/networkmanagercontroler.cpp +++ b/libnymea-app-core/wifisetup/networkmanagercontroller.cpp @@ -20,20 +20,19 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "networkmanagercontroler.h" -#include "engine.h" +#include "networkmanagercontroller.h" -NetworkManagerControler::NetworkManagerControler(QObject *parent) : QObject(parent) +NetworkManagerController::NetworkManagerController(QObject *parent) : QObject(parent) { } -BluetoothDeviceInfo *NetworkManagerControler::bluetoothDeviceInfo() const +BluetoothDeviceInfo *NetworkManagerController::bluetoothDeviceInfo() const { return m_bluetoothDeviceInfo; } -void NetworkManagerControler::setBluetoothDeviceInfo(BluetoothDeviceInfo *bluetoothDeviceInfo) +void NetworkManagerController::setBluetoothDeviceInfo(BluetoothDeviceInfo *bluetoothDeviceInfo) { if (m_bluetoothDeviceInfo != bluetoothDeviceInfo) { m_bluetoothDeviceInfo = bluetoothDeviceInfo; @@ -41,12 +40,12 @@ void NetworkManagerControler::setBluetoothDeviceInfo(BluetoothDeviceInfo *blueto } } -WirelessSetupManager *NetworkManagerControler::manager() +WirelessSetupManager *NetworkManagerController::manager() { return m_wirelessSetupManager; } -void NetworkManagerControler::connectDevice() +void NetworkManagerController::connectDevice() { if (!m_bluetoothDeviceInfo) { qWarning() << "Can't connect to device. bluetoothDeviceInfo not set."; diff --git a/libnymea-app-core/wifisetup/networkmanagercontroler.h b/libnymea-app-core/wifisetup/networkmanagercontroller.h similarity index 91% rename from libnymea-app-core/wifisetup/networkmanagercontroler.h rename to libnymea-app-core/wifisetup/networkmanagercontroller.h index 626a0273..a6be5509 100644 --- a/libnymea-app-core/wifisetup/networkmanagercontroler.h +++ b/libnymea-app-core/wifisetup/networkmanagercontroller.h @@ -20,8 +20,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef NETWORKMANAGERCONTROLER_H -#define NETWORKMANAGERCONTROLER_H +#ifndef NETWORKMANAGERCONTROLLER_H +#define NETWORKMANAGERCONTROLLER_H #include #include @@ -29,14 +29,14 @@ #include "bluetoothdeviceinfo.h" #include "wirelesssetupmanager.h" -class NetworkManagerControler : public QObject +class NetworkManagerController : public QObject { Q_OBJECT Q_PROPERTY(BluetoothDeviceInfo* bluetoothDeviceInfo READ bluetoothDeviceInfo WRITE setBluetoothDeviceInfo) Q_PROPERTY(WirelessSetupManager *manager READ manager NOTIFY managerChanged) public: - explicit NetworkManagerControler(QObject *parent = nullptr); + explicit NetworkManagerController(QObject *parent = nullptr); BluetoothDeviceInfo* bluetoothDeviceInfo() const; void setBluetoothDeviceInfo(BluetoothDeviceInfo* bluetoothDeviceInfo); @@ -57,4 +57,4 @@ signals: }; -#endif // NETWORKMANAGERCONTROLER_H +#endif // NETWORKMANAGERCONTROLLER_H diff --git a/libnymea-app-core/wifisetup/wirelessaccesspoint.cpp b/libnymea-app-core/wifisetup/wirelessaccesspoint.cpp index 365865d9..2e010553 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspoint.cpp +++ b/libnymea-app-core/wifisetup/wirelessaccesspoint.cpp @@ -100,18 +100,3 @@ void WirelessAccessPoint::setProtected(const bool &isProtected) emit isProtectedChanged(m_isProtected); } - -bool WirelessAccessPoint::selectedNetwork() const -{ - return m_selectedNetwork; -} - -void WirelessAccessPoint::setSelectedNetwork(bool selected) -{ - if (m_selectedNetwork == selected) - return; - - qDebug() << "Selected network changed" << m_ssid << selected; - m_selectedNetwork = selected; - emit selectedNetworkChanged(m_selectedNetwork); -} diff --git a/libnymea-app-core/wifisetup/wirelessaccesspoint.h b/libnymea-app-core/wifisetup/wirelessaccesspoint.h index ab24b11f..75773b7e 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspoint.h +++ b/libnymea-app-core/wifisetup/wirelessaccesspoint.h @@ -34,10 +34,9 @@ class WirelessAccessPoint : public QObject Q_PROPERTY(QString hostAddress READ hostAddress NOTIFY hostAddressChanged) Q_PROPERTY(int signalStrength READ signalStrength NOTIFY signalStrengthChanged) Q_PROPERTY(bool isProtected READ isProtected NOTIFY isProtectedChanged) - Q_PROPERTY(bool selectedNetwork READ selectedNetwork WRITE setSelectedNetwork NOTIFY selectedNetworkChanged) public: - WirelessAccessPoint(QObject *parent = 0); + WirelessAccessPoint(QObject *parent = nullptr); QString ssid() const; void setSsid(const QString ssid); @@ -54,16 +53,12 @@ public: bool isProtected() const; void setProtected(const bool &isProtected); - bool selectedNetwork() const; - void setSelectedNetwork(bool selected); - private: QString m_ssid; QString m_macAddress; QString m_hostAddress; int m_signalStrength = 0; bool m_isProtected = false; - bool m_selectedNetwork = false; signals: void ssidChanged(const QString &ssid); @@ -71,7 +66,6 @@ signals: void hostAddressChanged(const QString &hostAddress); void signalStrengthChanged(int signalStrength); void isProtectedChanged(bool isProtected); - void selectedNetworkChanged(bool selectedNetwork); }; #endif // WIRELESSACCESSPOINT_H diff --git a/libnymea-app-core/wifisetup/wirelessaccesspoints.cpp b/libnymea-app-core/wifisetup/wirelessaccesspoints.cpp index cc245e93..22d0ffc5 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspoints.cpp +++ b/libnymea-app-core/wifisetup/wirelessaccesspoints.cpp @@ -71,8 +71,6 @@ QVariant WirelessAccessPoints::data(const QModelIndex &index, int role) const return accessPoint->signalStrength(); } else if (role == WirelessAccesspointRoleProtected) { return accessPoint->isProtected(); - } else if (role == WirelessAccesspointRoleSelectedNetwork) { - return accessPoint->selectedNetwork(); } return QVariant(); @@ -120,11 +118,6 @@ void WirelessAccessPoints::addWirelessAccessPoint(WirelessAccessPoint *accessPoi m_wirelessAccessPoints.append(accessPoint); endInsertRows(); - connect(accessPoint, &WirelessAccessPoint::selectedNetworkChanged, this, [accessPoint, this]() { - int idx = m_wirelessAccessPoints.indexOf(accessPoint); - if (idx < 0) return; - emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleSelectedNetwork}); - }); connect(accessPoint, &WirelessAccessPoint::signalStrengthChanged, this, [accessPoint, this]() { int idx = m_wirelessAccessPoints.indexOf(accessPoint); if (idx < 0) return; @@ -150,14 +143,6 @@ void WirelessAccessPoints::removeWirelessAccessPoint(WirelessAccessPoint *access emit countChanged(); } -void WirelessAccessPoints::clearSelectedNetwork() -{ - foreach (WirelessAccessPoint *accessPoint, m_wirelessAccessPoints) { - accessPoint->setSelectedNetwork(false); - accessPoint->setHostAddress(QString()); - } -} - QHash WirelessAccessPoints::roleNames() const { QHash roles; @@ -166,7 +151,6 @@ QHash WirelessAccessPoints::roleNames() const roles[WirelessAccesspointRoleHostAddress] = "hostAddress"; roles[WirelessAccesspointRoleSignalStrength] = "signalStrength"; roles[WirelessAccesspointRoleProtected] = "protected"; - roles[WirelessAccesspointRoleSelectedNetwork] = "selectedNetwork"; return roles; } diff --git a/libnymea-app-core/wifisetup/wirelessaccesspoints.h b/libnymea-app-core/wifisetup/wirelessaccesspoints.h index 2d6848ca..a40043a3 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspoints.h +++ b/libnymea-app-core/wifisetup/wirelessaccesspoints.h @@ -39,11 +39,10 @@ public: WirelessAccesspointRoleMacAddress, WirelessAccesspointRoleHostAddress, WirelessAccesspointRoleSignalStrength, - WirelessAccesspointRoleProtected, - WirelessAccesspointRoleSelectedNetwork + WirelessAccesspointRoleProtected }; - explicit WirelessAccessPoints(QObject *parent = 0); + explicit WirelessAccessPoints(QObject *parent = nullptr); QList wirelessAccessPoints(); void setWirelessAccessPoints(QList wirelessAccessPoints); @@ -60,8 +59,6 @@ public: void addWirelessAccessPoint(WirelessAccessPoint *accessPoint); void removeWirelessAccessPoint(WirelessAccessPoint *accessPoint); - Q_INVOKABLE void clearSelectedNetwork(); - signals: void countChanged(); diff --git a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp index 1a80e31a..f76da4c4 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp +++ b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp @@ -42,43 +42,12 @@ void WirelessAccessPointsProxy::setAccessPoints(WirelessAccessPoints *accessPoin m_accessPoints = accessPoints; emit accessPointsChanged(); setSourceModel(m_accessPoints); - sort(0); - invalidate(); -} - -bool WirelessAccessPointsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - Q_UNUSED(source_parent) - Q_UNUSED(source_row) - - // Filter out the current selected network -// WirelessAccessPoint *accessPoint = m_accessPoints->get(source_row); - -// // Filter out selected network -// if (accessPoint->selectedNetwork()) -// return false; - - return true; -} - -bool WirelessAccessPointsProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const -{ - WirelessAccessPoint *leftAccessPoint = m_accessPoints->get(left.row()); - WirelessAccessPoint *rightAccessPoint = m_accessPoints->get(right.row()); - - if (leftAccessPoint->selectedNetwork()) - return true; - - return leftAccessPoint->signalStrength() > rightAccessPoint->signalStrength(); + connect(accessPoints, &WirelessAccessPoints::countChanged, this, &WirelessAccessPointsProxy::countChanged); + setSortRole(WirelessAccessPoints::WirelessAccesspointRoleSignalStrength); + sort(0, Qt::DescendingOrder); } WirelessAccessPoint *WirelessAccessPointsProxy::get(int index) const { return m_accessPoints->get(mapToSource(this->index(index, 0)).row()); } - -void WirelessAccessPointsProxy::invokeSort() -{ - sort(0); - invalidate(); -} diff --git a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.h b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.h index f8dafb0a..c1eef7ce 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.h +++ b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.h @@ -32,6 +32,8 @@ class WirelessAccessPoints; class WirelessAccessPointsProxy : public QSortFilterProxyModel { Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + Q_PROPERTY(WirelessAccessPoints* accessPoints READ accessPoints WRITE setAccessPoints) public: explicit WirelessAccessPointsProxy(QObject *parent = nullptr); @@ -40,21 +42,13 @@ public: Q_INVOKABLE WirelessAccessPoint* get(int index) const; - Q_INVOKABLE void invokeSort(); - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; +signals: + void countChanged(); + void accessPointsChanged(); private: WirelessAccessPoints *m_accessPoints = nullptr; -signals: - void accessPointsChanged(); - -public slots: - - }; #endif // WIRELESSACCESSPOINTSPROXY_H diff --git a/libnymea-app-core/wifisetup/wirelesssetupmanager.cpp b/libnymea-app-core/wifisetup/wirelesssetupmanager.cpp index a3cf9de9..ecfe31ca 100644 --- a/libnymea-app-core/wifisetup/wirelesssetupmanager.cpp +++ b/libnymea-app-core/wifisetup/wirelesssetupmanager.cpp @@ -46,11 +46,8 @@ static QBluetoothUuid systemResponseCharacteristicUuid = QBluetoothUuid(QUuid(" WirelessSetupManager::WirelessSetupManager(const QBluetoothDeviceInfo &deviceInfo, QObject *parent) : BluetoothDevice(deviceInfo, parent), - m_accessPoints(new WirelessAccessPoints(this)), - m_accessPointsProxy(new WirelessAccessPointsProxy(this)) + m_accessPoints(new WirelessAccessPoints(this)) { - m_accessPointsProxy->setAccessPoints(m_accessPoints); - connect(this, &WirelessSetupManager::connectedChanged, this, &WirelessSetupManager::onConnectedChanged); connect(this, &WirelessSetupManager::serviceDiscoveryFinished, this, &WirelessSetupManager::onServiceDiscoveryFinished); } @@ -85,11 +82,6 @@ bool WirelessSetupManager::initialized() const return m_initialized; } -bool WirelessSetupManager::initializing() const -{ - return m_initializing; -} - bool WirelessSetupManager::working() const { return m_working; @@ -115,14 +107,14 @@ bool WirelessSetupManager::wirelessEnabled() const return m_wirelessEnabled; } -WirelessAccessPoints *WirelessSetupManager::accessPoints() +WirelessAccessPoints *WirelessSetupManager::accessPoints() const { return m_accessPoints; } -WirelessAccessPointsProxy *WirelessSetupManager::accessPointsProxy() +WirelessAccessPoint *WirelessSetupManager::currentConnection() const { - return m_accessPointsProxy; + return m_currentConnection; } void WirelessSetupManager::reloadData() @@ -149,7 +141,8 @@ void WirelessSetupManager::loadNetworks() m_inputDataStream.clear(); setStatusText("WifiSetupManager: Loading wifi network list..."); - setWorking(true); + m_working = true; + emit workingChanged(); QVariantMap request; request.insert("c", (int)WirelessServiceCommandGetNetworks); @@ -175,7 +168,8 @@ void WirelessSetupManager::loadCurrentConnection() m_inputDataStream.clear(); setStatusText("WifiSetupManager: Loading current connection data"); - setWorking(true); + m_working = true; + emit workingChanged(); QVariantMap request; request.insert("c", (int)WirelessServiceCommandGetCurrentConnection); @@ -198,7 +192,8 @@ void WirelessSetupManager::performWifiScan() } setStatusText("WifiSetupManager: Perform refresh..."); - setWorking(true); + m_working = true; + emit workingChanged(); QVariantMap request; request.insert("c", (int)WirelessServiceCommandScan); @@ -340,8 +335,6 @@ void WirelessSetupManager::checkInitialized() if (initialized && m_wirelessEnabled && m_networkingEnabled) { loadNetworks(); } - - setInitialized(initialized); } void WirelessSetupManager::setModelNumber(const QString &modelNumber) @@ -374,36 +367,6 @@ void WirelessSetupManager::setHardwareRevision(const QString &hardwareRevision) emit hardwareRevisionChanged(); } -void WirelessSetupManager::setInitializing(bool initializing) -{ - if (m_initializing == initializing) - return; - - qDebug() << "WifiSetupManager:" << (initializing ? "initializing" : "not initializing"); - m_initializing = initializing; - emit initializingChanged(); -} - -void WirelessSetupManager::setInitialized(bool initialized) -{ - if (m_initialized == initialized) - return; - - qDebug() << "WifiSetupManager:" << (initialized ? "initialized" : "not initialized"); - m_initialized = initialized; - emit initializedChanged(); -} - -void WirelessSetupManager::setWorking(bool working) -{ - if (m_working == working) - return; - - qDebug() << "WifiSetupManager:" << (working ? "working" : "not working"); - m_working = working; - emit workingChanged(); -} - void WirelessSetupManager::setNetworkStatus(int networkStatus) { if (m_networkStatus == networkStatus) @@ -491,16 +454,16 @@ void WirelessSetupManager::processNetworkResponse(const QVariantMap &response) switch (responseCode) { case NetworkServiceResponseIvalidValue: - emit errorOccured(tr("Invalid value.")); + emit errorOccurred(tr("Invalid value.")); break; case NetworkServiceResponseNetworkManagerNotAvailable: - emit errorOccured(tr("There is no networkmanager available on the device.")); + emit errorOccurred(tr("There is no networkmanager available on the device.")); break; case NetworkServiceResponseWirelessNotAvailable: - emit errorOccured(tr("There is no wireless device available on the device.")); + emit errorOccurred(tr("There is no wireless device available on the device.")); break; default: - emit errorOccured(tr("Unknown error occured.")); + emit errorOccurred(tr("Unknown error occured.")); break; } @@ -512,7 +475,8 @@ void WirelessSetupManager::processNetworkResponse(const QVariantMap &response) void WirelessSetupManager::processWifiResponse(const QVariantMap &response) { - setWorking(false); + m_working = false; + emit workingChanged(); if (!response.contains("c") || !response.contains("r")) { qWarning() << "WifiSetupManager: Got invalid response map."; @@ -527,25 +491,25 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response) switch (responseCode) { case WirelessServiceResponseIvalidCommand: - emit errorOccured(tr("Invalid command.")); + emit errorOccurred(tr("Invalid command.")); break; case WirelessServiceResponseIvalidParameters: - emit errorOccured(tr("Invalid parameters.")); + emit errorOccurred(tr("Invalid parameters.")); break; case WirelessServiceResponseNetworkManagerNotAvailable: - emit errorOccured(tr("There is no networkmanager available on the device.")); + emit errorOccurred(tr("There is no networkmanager available on the device.")); break; case WirelessServiceResponseWirelessNotAvailable: - emit errorOccured(tr("There is no wireless device available on the device.")); + emit errorOccurred(tr("There is no wireless device available on the device.")); break; case WirelessServiceResponseWirelessNotEnabled: - emit errorOccured(tr("The wireless networking is disabled on the device.")); + emit errorOccurred(tr("The wireless networking is disabled on the device.")); break; case WirelessServiceResponseNetworkingNotEnabled: - emit errorOccured(tr("The networking is disabled on the device.")); + emit errorOccurred(tr("The networking is disabled on the device.")); break; default: - emit errorOccured(tr("Unknown error occured.")); + emit errorOccurred(tr("Unknown error occured.")); break; } @@ -569,12 +533,10 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response) accessPoint->setMacAddress(accessPointVariantMap.value("m").toString()); accessPoint->setSignalStrength(accessPointVariantMap.value("s").toInt()); accessPoint->setProtected(accessPointVariantMap.value("p").toBool()); - accessPoint->setSelectedNetwork(false); accessPoint->setHostAddress(""); m_accessPoints->addWirelessAccessPoint(accessPoint); } - m_accessPointsProxy->setAccessPoints(m_accessPoints); loadCurrentConnection(); @@ -595,17 +557,20 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response) QVariantMap currentConnection = response.value("p").toMap();; // Find current network + m_currentConnection = nullptr; QString macAddress = currentConnection.value("m").toString(); foreach (WirelessAccessPoint *accessPoint, m_accessPoints->wirelessAccessPoints()) { if (accessPoint->macAddress() == macAddress) { // Set the current network - accessPoint->setSelectedNetwork(true); + m_currentConnection = accessPoint; accessPoint->setHostAddress(currentConnection.value("i").toString()); - } else { - accessPoint->setSelectedNetwork(false); - accessPoint->setHostAddress(QString()); } } + qDebug() << "current connection is:" << m_currentConnection; + emit currentConnectionChanged(); + + m_initialized = true; + emit initializedChanged(); break; } @@ -616,7 +581,8 @@ void WirelessSetupManager::processWifiResponse(const QVariantMap &response) void WirelessSetupManager::processSystemResponse(const QVariantMap &response) { - setWorking(false); + m_working = false; + emit workingChanged(); if (!response.contains("c") || !response.contains("r")) { qWarning() << "WifiSetupManager: Got invalid response map."; @@ -659,9 +625,10 @@ void WirelessSetupManager::onConnectedChanged() m_accessPoints->clearModel(); - setInitialized(false); - setInitializing(false); - setWorking(false); + m_initialized = false; + emit initializedChanged(); + m_working = false; + emit workingChanged(); setManufacturer(""); setModelNumber(""); @@ -673,8 +640,6 @@ void WirelessSetupManager::onConnectedChanged() void WirelessSetupManager::onServiceDiscoveryFinished() { - setInitializing(true); - foreach (const QBluetoothUuid &serviceUuid, controller()->services()) { qDebug() << "WifiSetupManager: -->" << serviceUuid.toString(); } @@ -812,7 +777,8 @@ void WirelessSetupManager::onNetworkServiceStateChanged(const QLowEnergyService: m_netwokService->writeDescriptor(wirelessEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); setStatusText("Connected and ready"); - setWorking(false); + m_working = false; + emit workingChanged(); // Done with discovery setNetworkStatus(networkCharacteristic.value().toHex().toUInt(0, 16)); @@ -846,7 +812,10 @@ void WirelessSetupManager::onNetworkServiceCharacteristicChanged(const QLowEnerg { if (characteristic.uuid() == networkStatusCharacteristicUuid) { qDebug() << "Network status changed:" << value; - setNetworkStatus(value.toHex().toUInt(0, 16)); + setNetworkStatus(value.toHex().toInt(nullptr, 16)); + if (m_networkStatus == NetworkStatusGlobal) { + loadCurrentConnection(); + } return; } else if (characteristic.uuid() == networkResponseCharacteristicUuid) { // Check if currently reading @@ -915,7 +884,6 @@ void WirelessSetupManager::onWifiServiceStateChanged(const QLowEnergyService::Se m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiStatusCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); setWirelessStatus(m_wifiService->characteristic(wifiStatusCharacteristicUuid).value().toHex().toUInt(0, 16)); - m_accessPointsProxy->invokeSort(); // System service if (!m_systemService) { @@ -974,8 +942,11 @@ void WirelessSetupManager::onWifiServiceCharacteristicChanged(const QLowEnergyCh } if (characteristic.uuid() == wifiStatusCharacteristicUuid) { - qDebug() << "Wireless status changed:" << value; - setWirelessStatus(value.toHex().toUInt(0, 16)); + qDebug() << "Wireless status changed:" << value.toHex().toUInt(nullptr, 16) << "Old status:" << m_wirelessStatus; + setWirelessStatus(value.toHex().toInt(nullptr, 16)); + if (m_wirelessStatus == WirelessStatusActivated) { + loadCurrentConnection(); + } return; } diff --git a/libnymea-app-core/wifisetup/wirelesssetupmanager.h b/libnymea-app-core/wifisetup/wirelesssetupmanager.h index 51bf5486..3f8523ce 100644 --- a/libnymea-app-core/wifisetup/wirelesssetupmanager.h +++ b/libnymea-app-core/wifisetup/wirelesssetupmanager.h @@ -36,12 +36,10 @@ class WirelessSetupManager : public BluetoothDevice { Q_OBJECT Q_PROPERTY(bool working READ working NOTIFY workingChanged) - Q_PROPERTY(bool initializing READ initializing NOTIFY initializingChanged) - Q_PROPERTY(bool initialized READ initialized NOTIFY initializedChanged) Q_PROPERTY(WirelessAccessPoints *accessPoints READ accessPoints CONSTANT) - Q_PROPERTY(WirelessAccessPointsProxy *accessPointsProxy READ accessPointsProxy CONSTANT) + Q_PROPERTY(WirelessAccessPoint *currentConnection READ currentConnection NOTIFY currentConnectionChanged) Q_PROPERTY(QString modelNumber READ modelNumber NOTIFY modelNumberChanged) Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged) @@ -150,7 +148,6 @@ public: QString hardwareRevision() const; bool initialized() const; - bool initializing() const; bool working() const; NetworkStatus networkStatus() const; @@ -159,8 +156,8 @@ public: bool networkingEnabled() const; bool wirelessEnabled() const; - WirelessAccessPoints *accessPoints(); - WirelessAccessPointsProxy *accessPointsProxy(); + WirelessAccessPoints *accessPoints() const; + WirelessAccessPoint *currentConnection() const; void reloadData(); @@ -174,63 +171,6 @@ public: Q_INVOKABLE void disconnectWirelessNetwork(); Q_INVOKABLE void pressPushButton(); -private: - QLowEnergyService *m_deviceInformationService = nullptr; - QLowEnergyService *m_netwokService = nullptr; - QLowEnergyService *m_wifiService = nullptr; - QLowEnergyService *m_systemService = nullptr; - - WirelessAccessPoints *m_accessPoints = nullptr; - WirelessAccessPointsProxy *m_accessPointsProxy = nullptr; - - QString m_modelNumber; - QString m_manufacturer; - QString m_softwareRevision; - QString m_firmwareRevision; - QString m_hardwareRevision; - - bool m_networkingEnabled = false; - bool m_wirelessEnabled = false; - - bool m_working = false; - bool m_initialized = false; - bool m_initializing = false; - - NetworkStatus m_networkStatus = NetworkStatusUnknown; - WirelessStatus m_wirelessStatus = WirelessStatusUnknown; - - bool m_readingResponse = false; - QByteArray m_inputDataStream; - - QString m_ssid; - QString m_password; - - QVariantList m_accessPointsVariantList; - - void checkInitialized(); - - // Private set methods for read only properties - void setModelNumber(const QString &modelNumber); - void setManufacturer(const QString &manufacturer); - void setSoftwareRevision(const QString &softwareRevision); - void setFirmwareRevision(const QString &firmwareRevision); - void setHardwareRevision(const QString &hardwareRevision); - - void setInitializing(bool initializing); - void setInitialized(bool initialized); - void setWorking(bool working); - - void setNetworkStatus(int networkStatus); - void setWirelessStatus(int wirelessStatus); - void setNetworkingEnabled(bool networkingEnabled); - void setWirelessEnabled(bool wirelessEnabled); - - // Data methods - void streamData(const QVariantMap &request); - void processNetworkResponse(const QVariantMap &response); - void processWifiResponse(const QVariantMap &response); - void processSystemResponse(const QVariantMap &response); - signals: void modelNumberChanged(); void manufacturerChanged(); @@ -238,7 +178,6 @@ signals: void firmwareRevisionChanged(); void hardwareRevisionChanged(); - void initializingChanged(); void initializedChanged(); void workingChanged(); @@ -247,7 +186,9 @@ signals: void networkingEnabledChanged(); void wirelessEnabledChanged(); - void errorOccured(const QString &errorMessage); + void currentConnectionChanged(); + + void errorOccurred(const QString &errorMessage); private slots: void onConnectedChanged(); @@ -269,6 +210,58 @@ private slots: void onSystemServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value); void onSystemServiceReadFinished(const QLowEnergyCharacteristic &characteristic, const QByteArray &value); +private: + QLowEnergyService *m_deviceInformationService = nullptr; + QLowEnergyService *m_netwokService = nullptr; + QLowEnergyService *m_wifiService = nullptr; + QLowEnergyService *m_systemService = nullptr; + + WirelessAccessPoints *m_accessPoints = nullptr; + WirelessAccessPoint *m_currentConnection = nullptr; + + QString m_modelNumber; + QString m_manufacturer; + QString m_softwareRevision; + QString m_firmwareRevision; + QString m_hardwareRevision; + + bool m_networkingEnabled = false; + bool m_wirelessEnabled = false; + + bool m_working = false; + bool m_initialized = false; + + NetworkStatus m_networkStatus = NetworkStatusUnknown; + WirelessStatus m_wirelessStatus = WirelessStatusUnknown; + + bool m_readingResponse = false; + QByteArray m_inputDataStream; + + QString m_ssid; + QString m_password; + + QVariantList m_accessPointsVariantList; + + void checkInitialized(); + + // Private set methods for read only properties + void setModelNumber(const QString &modelNumber); + void setManufacturer(const QString &manufacturer); + void setSoftwareRevision(const QString &softwareRevision); + void setFirmwareRevision(const QString &firmwareRevision); + void setHardwareRevision(const QString &hardwareRevision); + + void setNetworkStatus(int networkStatus); + void setWirelessStatus(int wirelessStatus); + void setNetworkingEnabled(bool networkingEnabled); + void setWirelessEnabled(bool wirelessEnabled); + + // Data methods + void streamData(const QVariantMap &request); + void processNetworkResponse(const QVariantMap &response); + void processWifiResponse(const QVariantMap &response); + void processSystemResponse(const QVariantMap &response); + }; #endif // WIRELESSSETUPMANAGER_H diff --git a/libnymea-common/types/calendaritems.cpp b/libnymea-common/types/calendaritems.cpp index cd5bafaa..23d6d2b6 100644 --- a/libnymea-common/types/calendaritems.cpp +++ b/libnymea-common/types/calendaritems.cpp @@ -14,6 +14,8 @@ int CalendarItems::rowCount(const QModelIndex &parent) const QVariant CalendarItems::data(const QModelIndex &index, int role) const { + Q_UNUSED(index) + Q_UNUSED(role) return QVariant(); } diff --git a/libnymea-common/types/timeeventitems.cpp b/libnymea-common/types/timeeventitems.cpp index 3c90ac87..2f560cc8 100644 --- a/libnymea-common/types/timeeventitems.cpp +++ b/libnymea-common/types/timeeventitems.cpp @@ -16,6 +16,8 @@ int TimeEventItems::rowCount(const QModelIndex &parent) const QVariant TimeEventItems::data(const QModelIndex &index, int role) const { + Q_UNUSED(index) + Q_UNUSED(role) return QVariant(); } diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 63c24e04..fef6a472 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -3,18 +3,47 @@ ui/Nymea.qml ui/connection/ConnectPage.qml ui/connection/ManualConnectPage.qml - ui/connection/BluetoothDiscoveryPage.qml ui/connection/ConnectingPage.qml + ui/connection/wifisetup/BluetoothDiscoveryPage.qml + ui/connection/wifisetup/WirelessSetupPage.qml + ui/connection/wifisetup/ConnectWiFiPage.qml + ui/connection/wifisetup/NetworkSettingsPage.qml ui/mainviews/DevicesPage.qml ui/NewDeviceWizard.qml ui/SettingsPage.qml ui/components/GuhHeader.qml ui/components/HeaderButton.qml + ui/components/ColorPicker.qml + ui/components/ColorIcon.qml + ui/components/ThinDivider.qml + ui/components/ThrottledSlider.qml + ui/components/ColorPickerCt.qml + ui/components/IconMenuItem.qml + ui/components/Graph.qml + ui/components/ErrorDialog.qml + ui/components/InterfacesModels.qml + ui/components/ShutterControls.qml + ui/components/MeaDialog.qml + ui/components/MeaListItemDelegate.qml + ui/components/MainPageTabButton.qml + ui/components/AutoSizeMenu.qml + ui/components/EmptyViewPlaceholder.qml + ui/components/RemoveDeviceMethodDialog.qml + ui/components/FancyHeader.qml + ui/components/MainPageTile.qml + ui/components/BusyOverlay.qml + ui/components/AWSPasswordTextField.qml + ui/components/BrightnessSlider.qml + ui/components/SegmentedImage.qml + ui/components/SegmentRenderer.qml + ui/components/SegmentBoundingBoxes.qml + ui/components/FingerprintVisual.qml + ui/components/ListSectionHeader.qml + ui/components/ListFilterInput.qml ui/images/add.svg ui/images/back.svg ui/images/close.svg ui/images/info.svg - ui/components/ColorPicker.qml ui/customviews/CustomViewBase.qml ui/customviews/WeatherView.qml ui/customviews/MediaControllerView.qml @@ -25,7 +54,6 @@ ui/devicelistpages/GenericDeviceListPage.qml ui/devicelistpages/LightsDeviceListPage.qml ui/customviews/ExtendedVolumeController.qml - ui/components/ColorIcon.qml ui/images/light-on.svg ui/images/light-off.svg ui/images/media-preview-start.svg @@ -45,7 +73,6 @@ ui/images/media-seek-forward.svg ui/images/media-skip-backward.svg ui/images/media-skip-forward.svg - ui/components/ThinDivider.qml ui/images/weather-app-symbolic.svg ui/images/weathericons/weather-clear-day.svg ui/images/weathericons/weather-clear-night.svg @@ -61,15 +88,11 @@ ui/images/weathericons/humidity.svg ui/images/weathericons/wind.svg ui/devicepages/WeatherDevicePage.qml - ui/components/ThrottledSlider.qml - ui/components/ColorPickerCt.qml ui/images/navigation-menu.svg - ui/components/IconMenuItem.qml ui/images/settings.svg ui/images/stock_link.svg ui/images/share.svg ui/devicepages/SensorDevicePage.qml - ui/components/Graph.qml ui/images/sensors.svg ui/images/network-wired-symbolic.svg ui/images/notification.svg @@ -109,7 +132,6 @@ ui/images/go-down.svg ui/system/PluginsPage.qml ui/system/PluginParamsPage.qml - ui/components/ErrorDialog.qml ui/fonts/Ubuntu-B.ttf ui/fonts/Ubuntu-BI.ttf ui/fonts/Ubuntu-C.ttf @@ -119,7 +141,6 @@ ui/fonts/Ubuntu-MI.ttf ui/fonts/Ubuntu-R.ttf ui/fonts/Ubuntu-RI.ttf - ui/components/InterfacesModels.qml ui/magic/StateEvaluatorDelegate.qml ui/magic/EditStateEvaluatorPage.qml ui/magic/SimpleStateEvaluatorDelegate.qml @@ -139,7 +160,6 @@ qtquickcontrols2.conf ui/images/bluetooth.svg ui/images/refresh.svg - ui/WirelessControlerPage.qml ui/images/nm-signal-00.svg ui/images/nm-signal-00-secure.svg ui/images/nm-signal-25.svg @@ -174,14 +194,12 @@ ui/images/up.svg ui/devicepages/GarageGateDevicePage.qml ui/images/remove.svg - ui/components/ShutterControls.qml ../LICENSE ui/images/Built_with_Qt_RGB_logo.svg ui/images/Built_with_Qt_RGB_logo_vertical.svg ui/magic/TimeEventDelegate.qml ui/magic/EditTimeEventItemPage.qml ui/magic/EventDescriptorDelegate.qml - ui/components/MeaDialog.qml ui/magic/RuleActionDelegate.qml ui/magic/EditCalendarItemPage.qml ui/magic/CalendarItemDelegate.qml @@ -190,7 +208,6 @@ ui/images/event.svg ui/images/state.svg ui/images/event-interface.svg - ui/components/MeaListItemDelegate.qml ui/images/state-interface.svg ui/images/action-interface.svg ui/system/AboutNymeaPage.qml @@ -203,14 +220,9 @@ ui/images/starred.svg ui/images/non-starred.svg ui/images/slideshow.svg - ui/components/MainPageTabButton.qml ui/mainviews/ScenesView.qml ui/mainviews/FavoritesView.qml ui/mainviews/DevicesPageDelegate.qml - ui/components/AutoSizeMenu.qml - ui/components/EmptyViewPlaceholder.qml - ui/components/RemoveDeviceMethodDialog.qml - ui/components/FancyHeader.qml ui/images/awning/awning-100.svg ui/devicepages/AwningDevicePage.qml ui/images/awning/awning-000.svg @@ -232,7 +244,6 @@ ui/images/sensors/moisture.svg ui/images/sensors/pressure.svg ui/images/sensors/temperature.svg - ui/components/MainPageTile.qml ui/images/configure.svg ui/images/network-wifi-symbolic.svg ui/KeyboardLoader.qml @@ -240,14 +251,11 @@ ui/system/CloudSettingsPage.qml ui/images/cloud-offline.svg ui/images/cloud-error.svg - ui/components/BusyOverlay.qml - ui/components/AWSPasswordTextField.qml ui/appsettings/AboutPage.qml ui/appsettings/AppSettingsPage.qml ui/appsettings/DeveloperOptionsPage.qml ui/appsettings/CloudLoginPage.qml ui/devicepages/NotificationsDevicePage.qml - ui/components/BrightnessSlider.qml ui/devicepages/LightDevicePage.qml ui/devicelistpages/SensorsDeviceListPage.qml ui/devicelistpages/WeatherDeviceListPage.qml @@ -257,18 +265,13 @@ ui/devicepages/FingerprintReaderDevicePage.qml ui/images/account.svg ui/images/contact-new.svg - ui/components/SegmentedImage.qml - ui/components/SegmentRenderer.qml - ui/components/SegmentBoundingBoxes.qml - ui/components/FingerprintVisual.qml ui/images/fingerprint/fingerprint_boxes.json ui/images/fingerprint/fingerprint_segmented.png ui/images/fingerprint.svg - ui/components/ListSectionHeader.qml ui/images/find.svg ui/images/erase.svg - ui/components/ListFilterInput.qml ui/system/ConnectionInterfacesPage.qml ui/system/ConnectionInterfaceDelegate.qml + ui/connection/wifisetup/BoxInfoPage.qml diff --git a/nymea-app/ui/WirelessControlerPage.qml b/nymea-app/ui/WirelessControlerPage.qml deleted file mode 100644 index 4b51ff1c..00000000 --- a/nymea-app/ui/WirelessControlerPage.qml +++ /dev/null @@ -1,445 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 -import "components" - -Page { - id: root - - property string name - property string address - property QtObject networkManger - - header: GuhHeader { - text: qsTr("%1 box network setup").arg(app.systemName) - onBackPressed: { - pageStack.pop() - pageStack.pop() - } - - HeaderButton { - imageSource: Qt.resolvedUrl("images/refresh.svg") - onClicked: networkManger.manager.loadNetworks() - } - - HeaderButton { - imageSource: Qt.resolvedUrl("images/settings.svg") - onClicked: pageStack.push(settingsPage) - } - } - - Connections { - target: networkManger.manager - onErrorOccured: { - print("Error occurred", errorMessage) - var errorDialog = Qt.createComponent(Qt.resolvedUrl("components/ErrorDialog.qml")); - var popup = errorDialog.createObject(app, {text: errorMessage}) - popup.open() - } - - onWirelessStatusChanged: { - switch(networkManger.manager.wirelessStatus) { - case WirelessSetupManager.WirelessStatusDisconnected: - //networkManger.manager.loadCurrentConnection() - networkManger.manager.accessPoints.clearSelectedNetwork() - break; - case WirelessSetupManager.WirelessStatusActivated: - networkManger.manager.loadCurrentConnection() - break; - default: - break; - } - } - } - - function getWirelessStatusString() { - switch (networkManger.manager.wirelessStatus) { - case WirelessSetupManager.WirelessStatusUnknown: - return qsTr("Unknown status."); - case WirelessSetupManager.WirelessStatusUnmanaged: - return qsTr("Network unmanaged."); - case WirelessSetupManager.WirelessStatusUnavailable: - return qsTr("Network unavailable."); - case WirelessSetupManager.WirelessStatusDisconnected: - return qsTr("Disconnected."); - case WirelessSetupManager.WirelessStatusPrepare: - return qsTr("Prepare connection..."); - case WirelessSetupManager.WirelessStatusConfig: - return qsTr("Configure network..."); - case WirelessSetupManager.WirelessStatusNeedAuth: - return qsTr("Authentication needed"); - case WirelessSetupManager.WirelessStatusIpConfig: - return qsTr("Configuration IP..."); - case WirelessSetupManager.WirelessStatusIpCheck: - return qsTr("Check IP..."); - case WirelessSetupManager.WirelessStatusSecondaries: - return qsTr("Secondaries..."); - case WirelessSetupManager.WirelessStatusActivated: - return qsTr("Network connected."); - case WirelessSetupManager.WirelessStatusDeactivating: - return qsTr("Network disconnecting..."); - case WirelessSetupManager.WirelessStatusFailed: - return qsTr("Network connection failed."); - default: - return "???"; - } - - } - - function getNetworkStatusString() { - switch (networkManger.manager.networkStatus) { - case WirelessSetupManager.NetworkStatusUnknown: - return qsTr("Unknown status."); - case WirelessSetupManager.NetworkStatusAsleep: - return qsTr("Asleep."); - case WirelessSetupManager.NetworkStatusDisconnected: - return qsTr("Disconnected."); - case WirelessSetupManager.NetworkStatusDisconnecting: - return qsTr("Disconnecting..."); - case WirelessSetupManager.NetworkStatusConnecting: - return qsTr("Connecting..."); - case WirelessSetupManager.NetworkStatusLocal: - return qsTr("Connected local."); - case WirelessSetupManager.NetworkStatusConnectedSite: - return qsTr("Connected site."); - case WirelessSetupManager.NetworkStatusGlobal: - return qsTr("Online."); - default: - return "???" - } - } - - ColumnLayout { - anchors.fill: parent - visible: networkManger.manager.initialized - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Networking status") - subText: getNetworkStatusString() - } - - ThinDivider { - visible: networkManger.manager.wirelessEnabled - } - - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - - model: networkManger.manager.accessPointsProxy - clip: true - - BusyIndicator { - anchors.centerIn: parent - running: networkManger.manager.working - } - - delegate: MeaListItemDelegate { - width: parent.width - text: model.ssid - enabled: !networkManger.manager.working - subText: { - if (!model.selectedNetwork) { - return ""; - } - return getWirelessStatusString() - } - - iconColor: model.selectedNetwork ? app.accentColor : "#808080" - iconName: { - if (model.protected) { - if (model.signalStrength <= 25) - return Qt.resolvedUrl("images/nm-signal-25-secure.svg") - - if (model.signalStrength <= 50) - return Qt.resolvedUrl("images/nm-signal-50-secure.svg") - - if (model.signalStrength <= 75) - return Qt.resolvedUrl("images/nm-signal-75-secure.svg") - - if (model.signalStrength <= 100) - return Qt.resolvedUrl("images/nm-signal-100-secure.svg") - - } else { - - if (model.signalStrength <= 25) - return Qt.resolvedUrl("images/nm-signal-25.svg") - - if (model.signalStrength <= 50) - return Qt.resolvedUrl("images/nm-signal-50.svg") - - if (model.signalStrength <= 75) - return Qt.resolvedUrl("images/nm-signal-75.svg") - - if (model.signalStrength <= 100) - return Qt.resolvedUrl("images/nm-signal-100.svg") - - } - } - - onClicked: { - print("Connect to ", model.ssid, " --> ", model.macAddress) - if (model.selectedNetwork) { - pageStack.push(networkInformationPage, { ssid: model.ssid, macAddress: model.macAddress }) - } else { - pageStack.push(authenticationPage, { ssid: model.ssid, macAddress: model.macAddress }) - } - - } - } - } - } - - Component { - id: networkInformationPage - - Page { - id: root - - property string ssid - property string macAddress - property var accessPoint : networkManger.manager.accessPoints.getAccessPoint(ssid) - - header: GuhHeader { - text: qsTr("Network information") - onBackPressed: pageStack.pop() - } - - ColumnLayout { - anchors { left: parent.left; top: parent.top; right: parent.right } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("SSID:") - subText: root.ssid - } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Mac Address:") - subText: root.macAddress - } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Host Address:") - subText: accessPoint.hostAddress - } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Signal strength:") - subText: accessPoint.signalStrength - } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Protected:") - subText: accessPoint.isProtected ? "Protected" : "Open" - } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Connection status:") - subText: getWirelessStatusString() - } - - Button { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - text: qsTr("Disconnect") - onPressed: { - networkManger.manager.disconnectWirelessNetwork() - pageStack.pop() - } - } - } - } - } - - Component { - id: authenticationPage - - Page { - id: root - - property string ssid - property string macAddress - - header: GuhHeader { - text: qsTr("Wireless authentication") - onBackPressed: pageStack.pop() - } - - ColumnLayout { - anchors { left: parent.left; top: parent.top; right: parent.right } - - Label { - wrapMode: Text.WordWrap - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - Layout.topMargin: app.margins - text: qsTr("Please enter the password for the Wifi network.") - } - - MeaListItemDelegate { - Layout.fillWidth: true - text: ssid - subText: macAddress - progressive: false - } - - RowLayout { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - spacing: app.margins - - TextField { - id: passwordTextField - Layout.fillWidth: true - echoMode: TextInput.Password - } - ColorIcon { - Layout.preferredHeight: app.iconSize - Layout.preferredWidth: app.iconSize - name: "../images/eye.svg" - color: passwordTextField.echoMode === TextInput.Normal ? app.accentColor : keyColor - MouseArea { - anchors.fill: parent - anchors.margins: -app.margins / 2 - onClicked: { - if (passwordTextField.echoMode === TextInput.Normal) { - passwordTextField.echoMode = TextInput.Password - } else { - passwordTextField.echoMode = TextInput.Normal - } - } - } - } - } - - Button { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - text: qsTr("Connect") - onPressed: { - networkManger.manager.connectWirelessNetwork(ssid, passwordTextField.text) - var accessPoint = networkManger.manager.accessPoints.getAccessPoint(ssid) - networkManger.manager.accessPoints.clearSelectedNetwork() - accessPoint.selectedNetwork = true - pageStack.pop() - } - } - } - } - } - - Component { - id: settingsPage - - Page { - id: root - header: GuhHeader { - text: qsTr("Network manager settings") - onBackPressed: pageStack.pop() - } - - ColumnLayout { - anchors { left: parent.left; top: parent.top; right: parent.right } - - MeaListItemDelegate { - Layout.fillWidth: true - iconName: "../images/info.svg" - text: qsTr("About this %1 box").arg(app.systemName) - onClicked: pageStack.push(infoPage) - } - - SwitchDelegate { - Layout.fillWidth: true - text: qsTr("Networking") - checked: networkManger.manager.networkingEnabled - onClicked: networkManger.manager.enableNetworking(checked) - } - - SwitchDelegate { - Layout.fillWidth: true - enabled: networkManger.manager.networkingEnabled - text: qsTr("Wireless network") - checked: networkManger.manager.wirelessEnabled - onClicked: { - networkManger.manager.enableWireless(checked) - } - } - - Button { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - text: qsTr("Trigger a wireless scan on the device.") - onClicked: networkManger.manager.performWifiScan() - } - } - } - } - - Component { - id: infoPage - - Page { - id: root - header: GuhHeader { - text: qsTr("Box information") - onBackPressed: pageStack.pop() - } - - ColumnLayout { - anchors { left: parent.left; top: parent.top; right: parent.right } - - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("System UUID") - subText: networkManger.manager.modelNumber - } - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Manufacturer") - subText: networkManger.manager.manufacturer - } - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Software revision") - subText: networkManger.manager.softwareRevision - } - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Firmware revision") - subText: networkManger.manager.firmwareRevision - } - MeaListItemDelegate { - Layout.fillWidth: true - progressive: false - text: qsTr("Hardware revision") - subText: networkManger.manager.hardwareRevision - } - } - } - } -} diff --git a/nymea-app/ui/connection/ConnectPage.qml b/nymea-app/ui/connection/ConnectPage.qml index 63a4aa03..66c3f1a2 100644 --- a/nymea-app/ui/connection/ConnectPage.qml +++ b/nymea-app/ui/connection/ConnectPage.qml @@ -96,7 +96,7 @@ Page { title: qsTr("Connect %1").arg(app.systemName) model: ListModel { ListElement { iconSource: "../images/network-vpn.svg"; text: qsTr("Manual connection"); page: "ManualConnectPage.qml" } - ListElement { iconSource: "../images/bluetooth.svg"; text: qsTr("Wireless setup"); page: "BluetoothDiscoveryPage.qml"; } + ListElement { iconSource: "../images/bluetooth.svg"; text: qsTr("Wireless setup"); page: "wifisetup/BluetoothDiscoveryPage.qml"; } ListElement { iconSource: "../images/private-browsing.svg"; text: qsTr("Demo mode"); page: "" } ListElement { iconSource: "../images/stock_application.svg"; text: qsTr("App settings"); page: "../appsettings/AppSettingsPage.qml" } } @@ -104,7 +104,7 @@ Page { if (index === 2) { root.connectToHost("nymea://nymea.nymea.io:2222") } else { - pageStack.push(model.get(index).page); + pageStack.push(model.get(index).page, {nymeaDiscovery: discovery}); } } } @@ -278,7 +278,7 @@ Page { Layout.rightMargin: app.margins visible: discovery.discoveryModel.count === 0 text: qsTr("Start wireless setup") - onClicked: pageStack.push(Qt.resolvedUrl("BluetoothDiscoveryPage.qml")) + onClicked: pageStack.push(Qt.resolvedUrl("wifisetup/BluetoothDiscoveryPage.qml"), {nymeaDiscovery: discovery}) } Button { Layout.fillWidth: true diff --git a/nymea-app/ui/connection/BluetoothDiscoveryPage.qml b/nymea-app/ui/connection/wifisetup/BluetoothDiscoveryPage.qml similarity index 61% rename from nymea-app/ui/connection/BluetoothDiscoveryPage.qml rename to nymea-app/ui/connection/wifisetup/BluetoothDiscoveryPage.qml index 95f55cff..e9a3ac53 100644 --- a/nymea-app/ui/connection/BluetoothDiscoveryPage.qml +++ b/nymea-app/ui/connection/wifisetup/BluetoothDiscoveryPage.qml @@ -1,80 +1,74 @@ import QtQuick 2.4 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.2 -import "../components" +import "../../components" import Nymea 1.0 - Page { id: root header: GuhHeader { - text: qsTr("Bluetooth discovery") + text: qsTr("Wireless Box setup") onBackPressed: pageStack.pop() } - Component.onCompleted: bluetoothDiscovery.start() + property var nymeaDiscovery: null BluetoothDiscovery { id: bluetoothDiscovery + discoveryEnabled: pageStack.currentItem === root + } + + NetworkManagerController { + id: networkManager } function setupDevice(btDeviceInfo) { - bluetoothDiscovery.stop() - pageStack.push(connectingPageComponent, { bluetoothDeviceInfo: btDeviceInfo } ) + networkManager.bluetoothDeviceInfo = btDeviceInfo + networkManager.connectDevice(); + pageStack.push(connectingPageComponent) } Connections { - target: pageStack - onCurrentItemChanged: { - if (pageStack.currentItem === root) { - bluetoothDiscovery.start(); + target: networkManager.manager + onInitializedChanged: { + if (networkManager.manager.initialized) { + if (networkManager.manager.currentConnection) { + print("***** pushing WirelessSetupPage with networkManager:", networkManager) + pageStack.replace(Qt.resolvedUrl("WirelessSetupPage.qml"), { networkManagerController: networkManager, nymeaDiscovery: root.nymeaDiscovery } ) + } else { + var page = pageStack.replace(Qt.resolvedUrl("ConnectWiFiPage.qml"), { networkManagerController: networkManager } ) + page.connected.connect(function() { + print("connected signal received") + pageStack.replace(page, Qt.resolvedUrl("WirelessSetupPage.qml", {NetworkManagerController: networkManager, nymeaDiscovery: root.nymeaDiscovery})) + }) + } + } else { + pageStack.pop(root) + } + } + + onConnectedChanged: { + if (!networkManager.manager.connected) { + pageStack.pop(root) } } } ColumnLayout { anchors.fill: parent - spacing: app.margins + visible: bluetoothDiscovery.bluetoothAvailable && bluetoothDiscovery.bluetoothEnabled RowLayout { - spacing: app.margins - Layout.leftMargin: app.margins - Layout.topMargin: app.margins - Layout.rightMargin: app.rightMargin - + Layout.margins: app.margins Label { Layout.fillWidth: true - text: { - - if (Qt.platform.os === "ios") { - if (bluetoothDiscovery.bluetoothAvailable && bluetoothDiscovery.bluetoothEnabled) { - return qsTr("Searching for %1 boxes via Bluetooth LE.").arg(app.systemName) - } if (bluetoothDiscovery.bluetoothAvailable && !bluetoothDiscovery.bluetoothEnabled) { - return qsTr("Uh oh! Bluetooth is not enabled. Please enable the Bluetooth on this device and restart the application.") - } else { - return qsTr("Uh oh! Bluetooth is not available. Please make sure Bluetooth is enabled on this device and restart the application.") - } - } else { - if (bluetoothDiscovery.bluetoothAvailable && bluetoothDiscovery.bluetoothEnabled) { - return qsTr("Searching for %1 boxes via Bluetooth LE.").arg(app.systemName) - } if (bluetoothDiscovery.bluetoothAvailable && !bluetoothDiscovery.bluetoothEnabled) { - return qsTr("Uh oh! Bluetooth is not enabled. Please enable the Bluetooth on this device.") - } else { - return qsTr("Uh oh! Bluetooth is not available. Please make sure Bluetooth is enabled on this device.") - } - } - - - } - + text: qsTr("Searching for %1 boxes.").arg(app.systemName) wrapMode: Text.WordWrap } - BusyIndicator { running: bluetoothDiscovery.discovering } } - ThinDivider {} ListView { @@ -86,7 +80,7 @@ Page { delegate: MeaListItemDelegate { width: parent.width - iconName: Qt.resolvedUrl("../images/bluetooth.svg") + iconName: Qt.resolvedUrl("../../images/bluetooth.svg") text: model.name subText: model.address @@ -109,7 +103,7 @@ Page { wrapMode: Text.WordWrap maximumLineCount: 2 elide: Text.ElideRight - text: qsTr("Troubles finding your box? Try this!") + text: qsTr("Troubles finding your box?") } Button { text: qsTr("Help") @@ -118,12 +112,35 @@ Page { } } + ColumnLayout { + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins } + visible: !bluetoothDiscovery.bluetoothAvailable || !bluetoothDiscovery.bluetoothEnabled + spacing: app.margins * 2 + + Label { + Layout.fillWidth: true + text: qsTr("Uh oh") + color: app.accentColor + font.pixelSize: app.largeFont + } + + Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + + text: !bluetoothDiscovery.bluetoothAvailable + ? qsTr("Bluetooth doesn't seem to be available on this device. The wireless network setup requires a working Bluetooth connection.") + : qsTr("Bluetooth seems to be disabled. Please enable Bluetooth on your device in order to use the wireless network setup.") + } + } + + Component { id: helpPageComponent Page { id: helpPage header: GuhHeader { - text: qsTr("Setup help") + text: qsTr("Wireless setup help") onBackPressed: pageStack.pop() } @@ -159,7 +176,7 @@ Page { sourceSize.height: 540 fillMode: Image.PreserveAspectFit Layout.alignment: Qt.AlignHCenter - source: "../images/rpi-setup.svg" + source: "../../images/rpi-setup.svg" } ThinDivider {} Label { @@ -185,7 +202,7 @@ Page { sourceSize.height: width fillMode: Image.PreserveAspectFit Layout.alignment: Qt.AlignHCenter - source: "../images/nymea-box-setup.svg" + source: "../../images/nymea-box-setup.svg" } } } @@ -198,38 +215,13 @@ Page { Page { id: connectingPage header: GuhHeader { - text: qsTr("Establish bluetooth connection") + text: qsTr("Connecting...") onBackPressed: pageStack.pop() } - property var bluetoothDeviceInfo - - NetworkManagerControler { - id: networkManger - bluetoothDeviceInfo: connectingPage.bluetoothDeviceInfo - - Component.onCompleted: networkManger.connectDevice() - } - - Connections { - target: networkManger.manager - onInitializedChanged: { - if (networkManger.manager.initialized) { - pageStack.push(Qt.resolvedUrl("../WirelessControlerPage.qml"), { name: connectingPage.name, address: connectingPage.address, networkManger: networkManger } ) - } else { - pageStack.pop(root) - } - } - - onConnectedChanged: { - if (!networkManger.manager.connected) { - pageStack.pop(root) - } - } - } - ColumnLayout { - anchors.centerIn: parent + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins } + spacing: app.margins BusyIndicator { Layout.alignment: Qt.AlignHCenter @@ -238,14 +230,20 @@ Page { Label { id: workingMessage + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - text: networkManger.manager.statusText + text: networkManager.manager.statusText + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap } Label { id: initializingMessage + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - text: networkManger.manager.initializing ? qsTr("Initialize services...") : "" + text: networkManager.manager.initializing ? qsTr("Initializing services...") : "" + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap } } } diff --git a/nymea-app/ui/connection/wifisetup/BoxInfoPage.qml b/nymea-app/ui/connection/wifisetup/BoxInfoPage.qml new file mode 100644 index 00000000..71420d7d --- /dev/null +++ b/nymea-app/ui/connection/wifisetup/BoxInfoPage.qml @@ -0,0 +1,50 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.2 +import "../../components" +import Nymea 1.0 + +Page { + id: root + header: GuhHeader { + text: qsTr("Box information") + onBackPressed: pageStack.pop() + } + + property var networkManagerController: null + + ColumnLayout { + anchors { left: parent.left; top: parent.top; right: parent.right } + + MeaListItemDelegate { + Layout.fillWidth: true + progressive: false + text: qsTr("System UUID") + subText: networkManagerController.manager.modelNumber + } + MeaListItemDelegate { + Layout.fillWidth: true + progressive: false + text: qsTr("Manufacturer") + subText: networkManagerController.manager.manufacturer + } + MeaListItemDelegate { + Layout.fillWidth: true + progressive: false + text: qsTr("Software revision") + subText: networkManagerController.manager.softwareRevision + } + MeaListItemDelegate { + Layout.fillWidth: true + progressive: false + text: qsTr("Firmware revision") + subText: networkManagerController.manager.firmwareRevision + } + MeaListItemDelegate { + Layout.fillWidth: true + progressive: false + text: qsTr("Hardware revision") + subText: networkManagerController.manager.hardwareRevision + } + } +} diff --git a/nymea-app/ui/connection/wifisetup/ConnectWiFiPage.qml b/nymea-app/ui/connection/wifisetup/ConnectWiFiPage.qml new file mode 100644 index 00000000..92228db7 --- /dev/null +++ b/nymea-app/ui/connection/wifisetup/ConnectWiFiPage.qml @@ -0,0 +1,204 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import "../../components" +import Nymea 1.0 + +Page { + id: root + + property var networkManagerController: null + + signal connected(); + + header: GuhHeader { + text: qsTr("Select wireless network") + onBackPressed: { + pageStack.pop(); + } + + HeaderButton { + imageSource: "../images/info.svg" + onClicked: { + pageStack.push(Qt.resolvedUrl("BoxInfoPage.qml"), {networkManagerController: root.networkManagerController}) + } + } + HeaderButton { + imageSource: "../images/settings.svg" + onClicked: { + pageStack.push(Qt.resolvedUrl("NetworkSettingsPage.qml"), {networkManagerController: root.networkManagerController}) + } + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + + model: WirelessAccessPointsProxy { + accessPoints: networkManagerController.manager.accessPoints + } + clip: true + + delegate: MeaListItemDelegate { + width: parent.width + text: model.ssid + enabled: !networkManagerController.manager.working + subText: model.hostAddress + + iconColor: model.selectedNetwork ? app.accentColor : "#808080" + iconName: { + if (model.protected) { + if (model.signalStrength <= 25) + return Qt.resolvedUrl("../../images/nm-signal-25-secure.svg") + + if (model.signalStrength <= 50) + return Qt.resolvedUrl("../../images/nm-signal-50-secure.svg") + + if (model.signalStrength <= 75) + return Qt.resolvedUrl("../../images/nm-signal-75-secure.svg") + + if (model.signalStrength <= 100) + return Qt.resolvedUrl("../../images/nm-signal-100-secure.svg") + + } else { + + if (model.signalStrength <= 25) + return Qt.resolvedUrl("../../images/nm-signal-25.svg") + + if (model.signalStrength <= 50) + return Qt.resolvedUrl("../../images/nm-signal-50.svg") + + if (model.signalStrength <= 75) + return Qt.resolvedUrl("../../images/nm-signal-75.svg") + + if (model.signalStrength <= 100) + return Qt.resolvedUrl("../../images/nm-signal-100.svg") + + } + } + + onClicked: { + print("Connect to ", model.ssid, " --> ", model.macAddress) + if (model.selectedNetwork) { + pageStack.push(networkInformationPage, { ssid: model.ssid, macAddress: model.macAddress }) + } else { + pageStack.push(authenticationPageComponent, { ssid: model.ssid, macAddress: model.macAddress }) + } + } + } + } + } + + Component { + id: authenticationPageComponent + Page { + id: authenticationPage + header: GuhHeader { + text: qsTr("Authenticate") + onBackPressed: pageStack.pop() + } + + property string ssid + property string macAddress + + Connections { + target: root.networkManagerController.manager + onCurrentConnectionChanged: { + if (root.networkManagerController.manager.currentConnection && root.networkManagerController.manager.currentConnection.ssid === authenticationPage.ssid) { + print("**** connected!") + root.connected(); + } + } + onWirelessStatusChanged: { + print("Wireless status changed:", networkManagerController.manager.networkStatus) + if (networkManagerController.manager.wirelessStatus === WirelessSetupManager.WirelessStatusFailed) { + wrongPasswordText.visible = true + pageStack.pop(authenticationPage) + } + } + } + + ColumnLayout { + anchors { left: parent.left; top: parent.top; right: parent.right; } + + Label { + Layout.fillWidth: true + Layout.margins: app.margins + text: qsTr("Enter the password for %1").arg(authenticationPage.ssid) + wrapMode: Text.WordWrap + } + + RowLayout { + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + TextField { + id: passwordTextField + Layout.fillWidth: true + property bool showPassword: false + echoMode: showPassword ? TextInput.Normal : TextInput.Password + } + + ColorIcon { + Layout.preferredHeight: app.iconSize + Layout.preferredWidth: app.iconSize + name: "../images/eye.svg" + color: passwordTextField.showPassword ? app.accentColor : keyColor + MouseArea { + anchors.fill: parent + onClicked: passwordTextField.showPassword = !passwordTextField.showPassword + } + } + } + + Label { + id: wrongPasswordText + text: qsTr("Sorry, the password is wrong. Please try again.") + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + color: "red" + visible: false + } + + Button { + Layout.fillWidth: true + Layout.margins: app.margins + text: qsTr("OK") + enabled: passwordTextField.displayText.length >= 8 + onClicked: { + root.networkManagerController.manager.connectWirelessNetwork(authenticationPage.ssid, passwordTextField.text) + pageStack.push(connectingWifiWaitPageComponent, {ssid: authenticationPage.ssid }) + } + } + } + } + } + + Component { + id: connectingWifiWaitPageComponent + + Page { + id: connectingWifiWaitPage + property string ssid + + + ColumnLayout { + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins } + spacing: app.margins * 2 + BusyIndicator { + Layout.alignment: Qt.AlignHCenter + } + + Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + text: qsTr("Connecting the %1 box to %2").arg(app.systemName).arg(connectingWifiWaitPage.ssid) + } + } + } + } +} diff --git a/nymea-app/ui/connection/wifisetup/NetworkSettingsPage.qml b/nymea-app/ui/connection/wifisetup/NetworkSettingsPage.qml new file mode 100644 index 00000000..90b5b9b5 --- /dev/null +++ b/nymea-app/ui/connection/wifisetup/NetworkSettingsPage.qml @@ -0,0 +1,44 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.2 +import "../../components" +import Nymea 1.0 + +Page { + id: root + header: GuhHeader { + text: qsTr("Network settings") + onBackPressed: pageStack.pop() + } + + property var networkManagerController: null + + ColumnLayout { + anchors { left: parent.left; top: parent.top; right: parent.right } + + SwitchDelegate { + Layout.fillWidth: true + text: qsTr("Networking") + checked: networkManagerController.manager.networkingEnabled + onClicked: networkManagerController.manager.enableNetworking(checked) + } + + SwitchDelegate { + Layout.fillWidth: true + enabled: networkManagerController.manager.networkingEnabled + text: qsTr("Wireless network") + checked: networkManagerController.manager.wirelessEnabled + onClicked: { + networkManagerController.manager.enableWireless(checked) + } + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + text: qsTr("Trigger a wireless scan on the device.") + onClicked: networkManagerController.manager.performWifiScan() + } + } +} diff --git a/nymea-app/ui/connection/wifisetup/WirelessSetupPage.qml b/nymea-app/ui/connection/wifisetup/WirelessSetupPage.qml new file mode 100644 index 00000000..5e45abd6 --- /dev/null +++ b/nymea-app/ui/connection/wifisetup/WirelessSetupPage.qml @@ -0,0 +1,138 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import "../../components" +import Nymea 1.0 + +Page { + id: root + + property var networkManagerController: null + property var nymeaDiscovery: null + + header: GuhHeader { + text: qsTr("Wireless network setup") + onBackPressed: { + pageStack.pop(); + } + + HeaderButton { + imageSource: "../images/info.svg" + onClicked: { + pageStack.push(Qt.resolvedUrl("BoxInfoPage.qml"), {networkManagerController: root.networkManagerController}) + } + } + HeaderButton { + imageSource: "../images/settings.svg" + onClicked: { + pageStack.push(Qt.resolvedUrl("NetworkSettingsPage.qml"), {networkManagerController: root.networkManagerController}) + } + } + } + + Component.onCompleted: { + print("created with networkmanagercontroller:", root.networkManagerController) + updateConnectButton(); + } + + Connections { + target: root.networkManagerController.manager + onErrorOccurred: { + print("Error occurred", errorMessage) + var errorDialog = Qt.createComponent(Qt.resolvedUrl("../components/ErrorDialog.qml")); + var popup = errorDialog.createObject(app, {text: errorMessage}) + popup.open() + } + + onCurrentConnectionChanged: { + updateConnectButton(); + } + } + + Connections { + target: root.nymeaDiscovery.discoveryModel + onCountChanged: updateConnectButton(); + } + + function updateConnectButton() { + if (!root.networkManagerController.manager.currentConnection) { + connectButton.url = ""; + return; + } + + // FIXME: We should rather look for the UUID here, but nymea-networkmanager doesn't support getting us the nymea uuid (yet) + for (var i = 0; i < root.nymeaDiscovery.discoveryModel.count; i++) { + for (var j = 0; j < root.nymeaDiscovery.discoveryModel.get(i).connections.count; j++) { + if (root.nymeaDiscovery.discoveryModel.get(i).connections.get(j).url.toString().indexOf(root.networkManagerController.manager.currentConnection.hostAddress) >= 0) { + connectButton.url = root.nymeaDiscovery.discoveryModel.get(i).connections.get(j).url + return; + } + } + root.nymeaDiscovery.discoveryModel.get(i).connections.countChanged.connect(function() { + updateConnectButton(); + }) + } + connectButton.url = ""; + } + + ColumnLayout { + anchors { left: parent.left; top: parent.top; right: parent.right } + spacing: app.margins + ColorIcon { + Layout.preferredHeight: app.iconSize * 2 + Layout.preferredWidth: height + Layout.alignment: Qt.AlignCenter + name: "../images/tick.svg" + color: app.accentColor + } + Label { + Layout.fillWidth: true + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + wrapMode: Text.WordWrap + text: root.networkManagerController.manager.currentConnection + ? qsTr("Your %1 box is connected to %2").arg(app.systemName).arg(root.networkManagerController.manager.currentConnection.ssid) + : "" + } + + Label { + Layout.fillWidth: true + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + text: qsTr("IP address: %1").arg(root.networkManagerController.manager.currentConnection.hostAddress) + elide: Text.ElideRight + } + + Button { + id: connectButton + visible: url != "" + Layout.fillWidth: true + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + text: qsTr("Connect to box") + property string url + onClicked: { + engine.connection.connect(url) + } + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + text: qsTr("Change network") + onClicked: { + var page = pageStack.push(Qt.resolvedUrl("ConnectWiFiPage.qml"), {networkManagerController: root.networkManagerController}) + page.connected.connect(function() { + pageStack.pop(root) + }) + } + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins; Layout.rightMargin: app.margins + text: qsTr("Close wireless setup") + onClicked: { + pageStack.pop() + pageStack.pop() + } + } + } +}