diff --git a/libnymea-app-core/configuration/networkmanager.cpp b/libnymea-app-core/configuration/networkmanager.cpp index ca8c916d..1d25fbf4 100644 --- a/libnymea-app-core/configuration/networkmanager.cpp +++ b/libnymea-app-core/configuration/networkmanager.cpp @@ -4,18 +4,45 @@ #include "types/wirelessaccesspoint.h" #include "types/wirelessaccesspoints.h" +#include "engine.h" #include "jsonrpc/jsonrpcclient.h" #include #include -NetworkManager::NetworkManager(JsonRpcClient *jsonClient, QObject *parent): +NetworkManager::NetworkManager(QObject *parent): JsonHandler(parent), - m_jsonClient(jsonClient), m_wiredNetworkDevices(new WiredNetworkDevices(this)), m_wirelessNetworkDevices(new WirelessNetworkDevices(this)) { - m_jsonClient->registerNotificationHandler(this, "notificationReceived"); +} + +NetworkManager::~NetworkManager() +{ + if (m_engine) { + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + } +} + +void NetworkManager::setEngine(Engine *engine) +{ + if (m_engine && m_engine != engine) { + // clean up + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + } + + m_engine = engine; + emit engineChanged(); + + m_engine->jsonRpcClient()->registerNotificationHandler(this, "notificationReceived"); + init(); + + connect(m_engine->jsonRpcClient(), &JsonRpcClient::connectedChanged, this, &NetworkManager::init); +} + +Engine *NetworkManager::engine() const +{ + return m_engine; } QString NetworkManager::nameSpace() const @@ -28,9 +55,13 @@ void NetworkManager::init() m_wiredNetworkDevices->clear(); m_wirelessNetworkDevices->clear(); - m_jsonClient->sendCommand("NetworkManager.GetNetworkStatus", QVariantMap(), this, "getStatusReply"); - m_jsonClient->sendCommand("NetworkManager.GetNetworkDevices", QVariantMap(), this, "getDevicesReply"); -// m_jsonClient->sendCommand("NetworkManager.GetWirelessAccessPoints", QVariantMap(), this, "getAccessPointsReply"); + if (!m_engine->jsonRpcClient()->connected()) { + // Not ready yet... + return; + } + + m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetNetworkStatus", QVariantMap(), this, "getStatusReply"); + m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetNetworkDevices", QVariantMap(), this, "getDevicesReply"); } NetworkManager::NetworkManagerState NetworkManager::state() const @@ -62,21 +93,21 @@ void NetworkManager::enableNetworking(bool enable) { QVariantMap params; params.insert("enable", enable); - m_jsonClient->sendCommand("NetworkManager.EnableNetworking", params, this, "enableNetworkingReply"); + m_engine->jsonRpcClient()->sendCommand("NetworkManager.EnableNetworking", params, this, "enableNetworkingReply"); } void NetworkManager::enableWirelessNetworking(bool enable) { QVariantMap params; params.insert("enable", enable); - m_jsonClient->sendCommand("NetworkManager.EnableWirelessNetworking", params, this, "enableNetworkingReply"); + m_engine->jsonRpcClient()->sendCommand("NetworkManager.EnableWirelessNetworking", params, this, "enableNetworkingReply"); } void NetworkManager::refreshWifis(const QString &interface) { QVariantMap params; params.insert("interface", interface); - int requestId = m_jsonClient->sendCommand("NetworkManager.GetWirelessAccessPoints", params, this, "getAccessPointsReply"); + int requestId = m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetWirelessAccessPoints", params, this, "getAccessPointsReply"); m_apRequests.insert(requestId, interface); } @@ -86,14 +117,14 @@ void NetworkManager::connectToWiFi(const QString &interface, const QString &ssid params.insert("interface", interface); params.insert("ssid", ssid); params.insert("password", passphrase); - m_jsonClient->sendCommand("NetworkManager.ConnectWifiNetwork", params, this, "connectToWiFiReply"); + m_engine->jsonRpcClient()->sendCommand("NetworkManager.ConnectWifiNetwork", params, this, "connectToWiFiReply"); } void NetworkManager::disconnectInterface(const QString &interface) { QVariantMap params; params.insert("interface", interface); - m_jsonClient->sendCommand("NetworkManager.DisconnectInterface", params, this, "disconnectReply"); + m_engine->jsonRpcClient()->sendCommand("NetworkManager.DisconnectInterface", params, this, "disconnectReply"); } void NetworkManager::getStatusReply(const QVariantMap ¶ms) diff --git a/libnymea-app-core/configuration/networkmanager.h b/libnymea-app-core/configuration/networkmanager.h index a322677e..25a07722 100644 --- a/libnymea-app-core/configuration/networkmanager.h +++ b/libnymea-app-core/configuration/networkmanager.h @@ -6,7 +6,7 @@ #include "jsonrpc/jsonhandler.h" -class JsonRpcClient; +class Engine; class NetworkDevices; class WiredNetworkDevices; class WirelessNetworkDevices; @@ -14,6 +14,8 @@ class WirelessNetworkDevices; class NetworkManager : public JsonHandler { Q_OBJECT + Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged) + Q_PROPERTY(NetworkManagerState state READ state NOTIFY stateChanged) Q_PROPERTY(bool networkingEnabled READ networkingEnabled NOTIFY networkingEnabledChanged) Q_PROPERTY(bool wirelessNetworkingEnabled READ wirelessNetworkingEnabled NOTIFY wirelessNetworkingEnabledChanged) @@ -34,12 +36,14 @@ public: }; Q_ENUM(NetworkManagerState) - explicit NetworkManager(JsonRpcClient *jsonClient, QObject *parent = nullptr); + explicit NetworkManager(QObject *parent = nullptr); + ~NetworkManager(); + + void setEngine(Engine *engine); + Engine *engine() const; QString nameSpace() const override; - void init(); - NetworkManagerState state() const; bool networkingEnabled() const; bool wirelessNetworkingEnabled() const; @@ -56,6 +60,8 @@ public: Q_INVOKABLE void disconnectInterface(const QString &interface); private slots: + void init(); + void getStatusReply(const QVariantMap ¶ms); void getDevicesReply(const QVariantMap ¶ms); void getAccessPointsReply(const QVariantMap ¶ms); @@ -66,12 +72,13 @@ private slots: void notificationReceived(const QVariantMap ¶ms); signals: + void engineChanged(); void stateChanged(); void networkingEnabledChanged(); void wirelessNetworkingEnabledChanged(); private: - JsonRpcClient *m_jsonClient = nullptr; + Engine *m_engine = nullptr; NetworkManagerState m_state = NetworkManagerStateUnknown; bool m_networkingEnabled = false; diff --git a/libnymea-app-core/engine.cpp b/libnymea-app-core/engine.cpp index 568cf884..1e378069 100644 --- a/libnymea-app-core/engine.cpp +++ b/libnymea-app-core/engine.cpp @@ -42,8 +42,7 @@ Engine::Engine(QObject *parent) : m_logManager(new LogManager(m_jsonRpcClient, this)), m_tagsManager(new TagsManager(m_jsonRpcClient, this)), m_nymeaConfiguration(new NymeaConfiguration(m_jsonRpcClient, this)), - m_systemController(new SystemController(m_jsonRpcClient, this)), - m_networkManager(new NetworkManager(m_jsonRpcClient, this)) + m_systemController(new SystemController(m_jsonRpcClient, this)) { m_connection->registerTransport(new TcpSocketTransportFactory()); m_connection->registerTransport(new WebsocketTransportFactory()); @@ -106,11 +105,6 @@ SystemController *Engine::systemController() const return m_systemController; } -NetworkManager *Engine::networkManager() const -{ - return m_networkManager; -} - void Engine::deployCertificate() { if (!m_jsonRpcClient->connected()) { @@ -145,7 +139,6 @@ void Engine::onConnectedChanged() m_ruleManager->init(); m_nymeaConfiguration->init(); m_systemController->init(); - m_networkManager->init(); } } } diff --git a/libnymea-app-core/engine.h b/libnymea-app-core/engine.h index d890533f..754e1ef2 100644 --- a/libnymea-app-core/engine.h +++ b/libnymea-app-core/engine.h @@ -45,7 +45,6 @@ class Engine : public QObject Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient CONSTANT) Q_PROPERTY(NymeaConfiguration* nymeaConfiguration READ nymeaConfiguration CONSTANT) Q_PROPERTY(SystemController* systemController READ systemController CONSTANT) - Q_PROPERTY(NetworkManager* networkManager READ networkManager CONSTANT) public: explicit Engine(QObject *parent = nullptr); @@ -61,7 +60,6 @@ public: LogManager *logManager() const; NymeaConfiguration *nymeaConfiguration() const; SystemController *systemController() const; - NetworkManager *networkManager() const; Q_INVOKABLE void deployCertificate(); @@ -74,7 +72,6 @@ private: TagsManager *m_tagsManager; NymeaConfiguration *m_nymeaConfiguration; SystemController *m_systemController; - NetworkManager *m_networkManager; private slots: void onConnectedChanged(); diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index 9bcd7c76..c73a5844 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -50,11 +50,20 @@ QString JsonRpcClient::nameSpace() const void JsonRpcClient::registerNotificationHandler(JsonHandler *handler, const QString &method) { - if (m_notificationHandlers.contains(handler->nameSpace())) { - qWarning() << "Already have a notification handler for" << handler->nameSpace(); + if (m_notificationHandlerMethods.contains(handler)) { + qWarning() << "Notification handler" << handler << " already registered"; return; } - m_notificationHandlers.insert(handler->nameSpace(), qMakePair(handler, method)); + m_notificationHandlers.insert(handler->nameSpace(), handler); + m_notificationHandlerMethods.insert(handler, method); + setNotificationsEnabled(); +} + +void JsonRpcClient::unregisterNotificationHandler(JsonHandler *handler) +{ + m_notificationHandlers.remove(handler->nameSpace(), handler); + m_notificationHandlerMethods.remove(handler); + setNotificationsEnabled(); } int JsonRpcClient::sendCommand(const QString &method, const QVariantMap ¶ms, QObject *caller, const QString &callbackMethod) @@ -70,15 +79,6 @@ int JsonRpcClient::sendCommand(const QString &method, QObject *caller, const QSt return sendCommand(method, QVariantMap(), caller, callbackMethod); } -void JsonRpcClient::setNotificationsEnabled(bool enabled) -{ - QVariantMap params; - params.insert("enabled", enabled); - JsonRpcReply *reply = createReply("JSONRPC.SetNotificationStatus", params, this, "setNotificationsEnabledResponse"); - m_replies.insert(reply->commandId(), reply); - sendRequest(reply->requestMap()); -} - void JsonRpcClient::getCloudConnectionStatus() { JsonRpcReply *reply = createReply("JSONRPC.IsCloudConnected", QVariantMap(), this, "isCloudConnectedReply"); @@ -90,9 +90,10 @@ void JsonRpcClient::setNotificationsEnabledResponse(const QVariantMap ¶ms) { qDebug() << "Notifications enabled:" << params; - m_connected = true; - emit connectedChanged(true); - + if (!m_connected) { + m_connected = true; + emit connectedChanged(true); + } } void JsonRpcClient::notificationReceived(const QVariantMap &data) @@ -114,7 +115,7 @@ void JsonRpcClient::notificationReceived(const QVariantMap &data) settings.endGroup(); emit authenticationRequiredChanged(); - setNotificationsEnabled(true); + setNotificationsEnabled(); } else { emit pushButtonAuthFailed(); } @@ -261,7 +262,7 @@ void JsonRpcClient::processAuthenticate(const QVariantMap &data) settings.endGroup(); emit authenticationRequiredChanged(); - setNotificationsEnabled(true); + setNotificationsEnabled(); } else { qWarning() << "Authentication failed" << data; emit authenticationFailed(); @@ -302,6 +303,25 @@ JsonRpcReply *JsonRpcClient::createReply(const QString &method, const QVariantMa return new JsonRpcReply(m_id, callParts.first(), callParts.last(), params, caller, callback); } +void JsonRpcClient::setNotificationsEnabled() +{ + QStringList namespaces; + foreach (const QString &nameSpace, m_notificationHandlers.keys()) { + namespaces.append(nameSpace); + } + + QVariantMap params; + + if (ensureServerVersion("3.1")) { + params.insert("namespaces", namespaces); + } else { + params.insert("enabled", namespaces.count() > 0); + } + JsonRpcReply *reply = createReply("JSONRPC.SetNotificationStatus", params, this, "setNotificationsEnabledResponse"); + m_replies.insert(reply->commandId(), reply); + sendRequest(reply->requestMap()); +} + void JsonRpcClient::sendRequest(const QVariantMap &request) { QVariantMap newRequest = request; @@ -358,15 +378,9 @@ void JsonRpcClient::dataReceived(const QByteArray &data) // qDebug() << "Incoming notification:" << jsonDoc.toJson(); QStringList notification = dataMap.value("notification").toString().split("."); QString nameSpace = notification.first(); - JsonHandler *handler = m_notificationHandlers.value(nameSpace).first; - - if (!handler) { -// qWarning() << "JsonRpc: handler not implemented:" << nameSpace; - return; + foreach (JsonHandler *handler, m_notificationHandlers.values(nameSpace)) { + QMetaObject::invokeMethod(handler, m_notificationHandlerMethods.value(handler).toLatin1().data(), Q_ARG(QVariantMap, dataMap)); } - -// qDebug() << "Incoming notification:" << jsonDoc.toJson(); - QMetaObject::invokeMethod(handler, m_notificationHandlers.value(nameSpace).second.toLatin1().data(), Q_ARG(QVariantMap, dataMap)); return; } @@ -454,7 +468,7 @@ void JsonRpcClient::helloReply(const QVariantMap ¶ms) } } - setNotificationsEnabled(true); + setNotificationsEnabled(); getCloudConnectionStatus(); } diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.h b/libnymea-app-core/jsonrpc/jsonrpcclient.h index 09ff11d4..d095166e 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.h +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.h @@ -59,6 +59,7 @@ public: QString nameSpace() const override; void registerNotificationHandler(JsonHandler *handler, const QString &method); + void unregisterNotificationHandler(JsonHandler *handler); int sendCommand(const QString &method, const QVariantMap ¶ms, QObject *caller = nullptr, const QString &callbackMethod = QString()); int sendCommand(const QString &method, QObject *caller = nullptr, const QString &callbackMethod = QString()); @@ -107,8 +108,9 @@ private slots: private: int m_id; - // < namespace, > - QHash > m_notificationHandlers; + // < namespace, method> > + QHash m_notificationHandlerMethods; + QMultiHash m_notificationHandlers; QHash m_replies; NymeaConnection *m_connection = nullptr; @@ -126,7 +128,7 @@ private: QByteArray m_token; QByteArray m_receiveBuffer; - void setNotificationsEnabled(bool enabled); + void setNotificationsEnabled(); void getCloudConnectionStatus(); // json handler diff --git a/libnymea-app-core/libnymea-app-core.h b/libnymea-app-core/libnymea-app-core.h index de616f3b..64e6b004 100644 --- a/libnymea-app-core/libnymea-app-core.h +++ b/libnymea-app-core/libnymea-app-core.h @@ -223,7 +223,7 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "Repository", "Get it from Repositories"); qmlRegisterType(uri, 1, 0, "PackagesFilterModel"); - qmlRegisterUncreatableType(uri, 1, 0, "NetworkManager", "Get it from Engine"); + qmlRegisterType(uri, 1, 0, "NetworkManager"); qmlRegisterUncreatableType(uri, 1, 0, "NetworkDevices", "Get it from NetworkManager"); qmlRegisterUncreatableType(uri, 1, 0, "WiredNetworkDevices", "Get it from NetworkManager"); qmlRegisterUncreatableType(uri, 1, 0, "WirelessNetworkDevices", "Get it from NetworkManager"); diff --git a/nymea-app/ui/customviews/GenericTypeGraph.qml b/nymea-app/ui/customviews/GenericTypeGraph.qml index 73992b94..bb49843c 100644 --- a/nymea-app/ui/customviews/GenericTypeGraph.qml +++ b/nymea-app/ui/customviews/GenericTypeGraph.qml @@ -145,7 +145,6 @@ Item { labelsFont.pixelSize: app.smallFont labelsColor: app.foregroundColor property int timeDiff: (xAxis.max.getTime() - xAxis.min.getTime()) / 1000 - onTimeDiffChanged: print("timeDiff is:", timeDiff) function getTimeSpanString() { var td = timeDiff @@ -403,7 +402,6 @@ Item { interval: 1000 repeat: true onTriggered: { - print("autoscrolling chart") scrollMouseArea.scrollRightLimited(10) } } diff --git a/nymea-app/ui/system/NetworkSettingsPage.qml b/nymea-app/ui/system/NetworkSettingsPage.qml index 157b75ce..99affbc5 100644 --- a/nymea-app/ui/system/NetworkSettingsPage.qml +++ b/nymea-app/ui/system/NetworkSettingsPage.qml @@ -14,7 +14,10 @@ Page { } } - readonly property NetworkManager networkManager: engine.networkManager + NetworkManager { + id: networkManager + engine: _engine + } function networkStateToString(networkState) { switch (networkState) {