register the cloud service as a plugin in the devicemanager
implementing the notifications interface
This commit is contained in:
parent
05da66421d
commit
c1d4adea17
@ -159,6 +159,7 @@ void AWSConnector::setupSubscriptions()
|
||||
subscriptions.append(QString("%1/device/name/response").arg(m_clientId));
|
||||
subscriptions.append(QString("%1/device/users/response").arg(m_clientId));
|
||||
subscriptions.append(QString("%1/pair/response").arg(m_clientId));
|
||||
subscriptions.append(QString("%1/notify/response").arg(m_clientId));
|
||||
subscribe(subscriptions);
|
||||
|
||||
// fetch previous pairings
|
||||
@ -174,17 +175,36 @@ void AWSConnector::fetchPairings()
|
||||
publish(QString("%1/device/users").arg(m_clientId), params);
|
||||
}
|
||||
|
||||
void AWSConnector::onPairingsRetrieved(const QVariantList &pairings)
|
||||
void AWSConnector::onPairingsRetrieved(const QVariantMap &pairings)
|
||||
{
|
||||
qCDebug(dcAWS) << pairings.count() << "devices paired in cloud.";
|
||||
if (pairings.count() > 0) {
|
||||
qCDebug(dcAWS) << pairings.value("users").toList().count() << "devices paired in cloud.";
|
||||
if (pairings.value("users").toList().count() > 0) {
|
||||
QStringList topics;
|
||||
foreach (const QVariant &pairing, pairings) {
|
||||
foreach (const QVariant &pairing, pairings.value("users").toList()) {
|
||||
topics << QString("%1/%2/#").arg(m_clientId).arg(pairing.toString());
|
||||
}
|
||||
subscribe(topics);
|
||||
}
|
||||
|
||||
qCDebug(dcAWS) << pairings.value("pushNotificationsEndpoints").toList().count() << "push notification enabled users paired in cloud.";
|
||||
QList<PushNotificationsEndpoint> pushNotificationEndpoints;
|
||||
if (pairings.value("pushNotificationsEndpoints").toList().count() > 0) {
|
||||
foreach (const QVariant &pairing, pairings.value("pushNotificationsEndpoints").toList()) {
|
||||
foreach (const QString &cognitoUserId, pairing.toMap().keys()) {
|
||||
qCDebug(dcAWS()) << "User:" << cognitoUserId << "has" << pairing.toMap().value(cognitoUserId).toList().count() << "push notifications enabled devices.";
|
||||
foreach (const QVariant &endpoint, pairing.toMap().value(cognitoUserId).toList()) {
|
||||
PushNotificationsEndpoint ep;
|
||||
ep.userId = cognitoUserId;
|
||||
ep.endpointId = endpoint.toMap().value("endpointId").toString();
|
||||
ep.displayName = endpoint.toMap().value("displayName").toString();
|
||||
pushNotificationEndpoints.append(ep);
|
||||
qCDebug(dcAWS) << "Device:" << ep.displayName << "endpoint:" << ep.endpointId << "user:" << ep.userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emit pushNotificationEndpointsUpdated(pushNotificationEndpoints);
|
||||
|
||||
if (readSyncedNameCache() != m_clientName) {
|
||||
setName();
|
||||
}
|
||||
@ -237,6 +257,18 @@ void AWSConnector::sendWebRtcHandshakeMessage(const QString &sessionId, const QV
|
||||
publish(sessionId + "/reply", map);
|
||||
}
|
||||
|
||||
int AWSConnector::sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("id", ++m_transactionId);
|
||||
params.insert("command", "sendPushNotification");
|
||||
params.insert("title", title);
|
||||
params.insert("body", text);
|
||||
params.insert("timestamp", QDateTime::currentMSecsSinceEpoch());
|
||||
publish(QString("%1/notify/user/%2/%3").arg(m_clientId, userId, endpointId), params);
|
||||
return m_transactionId;
|
||||
}
|
||||
|
||||
quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message)
|
||||
{
|
||||
if (!m_setupInProgress && !isConnected()) {
|
||||
@ -418,7 +450,7 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam
|
||||
qCWarning(dcAWS()) << "Received a pairing response for a transaction we didn't start";
|
||||
}
|
||||
} else if (topic == QString("%1/device/users/response").arg(connector->m_clientId)) {
|
||||
connector->staticMetaObject.invokeMethod(connector, "onPairingsRetrieved", Qt::QueuedConnection, Q_ARG(QVariantList, jsonDoc.toVariant().toMap().value("users").toList()));
|
||||
connector->staticMetaObject.invokeMethod(connector, "onPairingsRetrieved", Qt::QueuedConnection, Q_ARG(QVariantMap, jsonDoc.toVariant().toMap()));
|
||||
} else if (topic == QString("%1/device/name/response").arg(connector->m_clientId)) {
|
||||
qCDebug(dcAWS) << "Set device name in cloud with status:" << jsonDoc.toVariant().toMap().value("status").toInt();
|
||||
if (jsonDoc.toVariant().toMap().value("status").toInt() == 200) {
|
||||
@ -438,6 +470,11 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam
|
||||
connector->webRtcHandshakeMessageReceived(topic, jsonDoc.toVariant().toMap());
|
||||
} else if (topic.startsWith(QString("%1/eu-west-1:").arg(connector->m_clientId)) && topic.contains("reply")) {
|
||||
// silently drop our own things (should not be subscribed to that in the first place)
|
||||
} else if (topic == QString("%1/notify/response").arg(connector->m_clientId)) {
|
||||
int transactionId = jsonDoc.toVariant().toMap().value("id").toInt();
|
||||
int status = jsonDoc.toVariant().toMap().value("status").toInt();
|
||||
qCDebug(dcAWS()) << "Push notification reply for transaction" << transactionId << " Status:" << status << jsonDoc.toVariant().toMap().value("message").toString();
|
||||
emit connector->pushNotificationSent(transactionId, status);
|
||||
} else {
|
||||
qCWarning(dcAWS) << "Unhandled subscription received!" << topic << QString::fromStdString(payload);
|
||||
}
|
||||
|
||||
@ -39,6 +39,13 @@ public:
|
||||
explicit AWSConnector(QObject *parent = 0);
|
||||
~AWSConnector();
|
||||
|
||||
class PushNotificationsEndpoint {
|
||||
public:
|
||||
QString userId;
|
||||
QString endpointId;
|
||||
QString displayName;
|
||||
};
|
||||
|
||||
void connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile);
|
||||
void disconnectAWS();
|
||||
bool isConnected() const;
|
||||
@ -48,11 +55,16 @@ public:
|
||||
|
||||
void sendWebRtcHandshakeMessage(const QString &sessionId, const QVariantMap &map);
|
||||
|
||||
public slots:
|
||||
int sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void devicePaired(const QString &cognritoUserId, int errorCode, const QString &message);
|
||||
void webRtcHandshakeMessageReceived(const QString &transactionId, const QVariantMap &data);
|
||||
void pushNotificationEndpointsUpdated(const QList<PushNotificationsEndpoint> pushNotificationEndpoints);
|
||||
void pushNotificationSent(int id, int status);
|
||||
|
||||
private slots:
|
||||
void doConnect();
|
||||
@ -61,7 +73,7 @@ private slots:
|
||||
void onDeviceRegistered(bool needsReconnect);
|
||||
void setupSubscriptions();
|
||||
void fetchPairings();
|
||||
void onPairingsRetrieved(const QVariantList &pairings);
|
||||
void onPairingsRetrieved(const QVariantMap &pairings);
|
||||
void setName();
|
||||
void onDisconnected();
|
||||
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
#include "awsconnector.h"
|
||||
#include "janusconnector.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "cloudnotifications.h"
|
||||
|
||||
|
||||
CloudManager::CloudManager(NetworkManager *networkManager, QObject *parent) : QObject(parent),
|
||||
m_networkManager(networkManager)
|
||||
@ -130,6 +132,12 @@ bool CloudManager::keepAlive(const QString &sessionId)
|
||||
return m_janusConnector->sendKeepAliveMessage(sessionId);
|
||||
}
|
||||
|
||||
CloudNotifications *CloudManager::createNotificationsPlugin() const
|
||||
{
|
||||
CloudNotifications* notifications = new CloudNotifications(m_awsConnector);
|
||||
return notifications;
|
||||
}
|
||||
|
||||
void CloudManager::connect2aws()
|
||||
{
|
||||
m_awsConnector->connect2AWS(m_serverUrl,
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
class JanusConnector;
|
||||
class AWSConnector;
|
||||
class CloudNotifications;
|
||||
|
||||
class CloudManager : public QObject
|
||||
{
|
||||
@ -51,6 +52,8 @@ public:
|
||||
|
||||
bool keepAlive(const QString &sessionId);
|
||||
|
||||
CloudNotifications* createNotificationsPlugin() const;
|
||||
|
||||
signals:
|
||||
void connectedChanged(bool connected);
|
||||
|
||||
@ -80,6 +83,8 @@ private:
|
||||
QString m_caCertificate;
|
||||
QString m_clientCertificate;
|
||||
QString m_clientCertificateKey;
|
||||
|
||||
CloudNotifications *m_notifications;
|
||||
};
|
||||
|
||||
#endif // CLOUDMANAGER_H
|
||||
|
||||
209
libguh-core/cloudnotifications.cpp
Normal file
209
libguh-core/cloudnotifications.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2017 Michael Zanetti <michael.zanetti@guh.io> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "cloudnotifications.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
DeviceClassId cloudNotificationsDeviceClassId = DeviceClassId("81c1bbcc-543a-48fd-bd18-ab6a76f9c38d");
|
||||
ParamTypeId cloudNotificationsDeviceClassUserParamId = ParamTypeId("5bdeaf08-91a9-42bc-a9f9-ef6b02ecaa3c");
|
||||
ParamTypeId cloudNotificationsDeviceClassEndpointParamId = ParamTypeId("e7c41785-dd3b-4f46-b5b4-1f8a7d060ddd");
|
||||
|
||||
ActionTypeId notifyActionTypeId = ActionTypeId("211d1f25-28e7-4eba-8938-b29de0e41571");
|
||||
ParamTypeId notifyActionParamTitleId = ParamTypeId("096503fc-b343-4d7f-8387-96162faf0f8e");
|
||||
ParamTypeId notifyActionParamBodyId = ParamTypeId("4bd0fa87-c663-4621-8040-99b6d535387c");
|
||||
|
||||
StateTypeId connectedStateTypeId = StateTypeId("518e27b6-c3bf-49d7-be24-05ae978c00f7");
|
||||
|
||||
CloudNotifications::CloudNotifications(AWSConnector* awsConnector, QObject *parent):
|
||||
DevicePlugin(parent),
|
||||
m_awsConnector(awsConnector)
|
||||
{
|
||||
connect(m_awsConnector, &AWSConnector::pushNotificationEndpointsUpdated, this, &CloudNotifications::pushNotificationEndpointsUpdated);
|
||||
connect(m_awsConnector, &AWSConnector::pushNotificationSent, this, &CloudNotifications::pushNotificationSent);
|
||||
}
|
||||
|
||||
QJsonObject CloudNotifications::metaData() const
|
||||
{
|
||||
QVariantMap pluginMetaData;
|
||||
pluginMetaData.insert("id", "ccc6dbc8-e352-48a1-8e87-3c89a4669fc2");
|
||||
pluginMetaData.insert("name", "cloudNotifications");
|
||||
pluginMetaData.insert("displayName", "Cloud Notifications");
|
||||
|
||||
QVariantList interfaces;
|
||||
interfaces.append("notifications");
|
||||
interfaces.append("connectable");
|
||||
|
||||
QVariantList createMethods;
|
||||
createMethods.append("auto");
|
||||
|
||||
QVariantMap userIdParam;
|
||||
userIdParam.insert("id", cloudNotificationsDeviceClassUserParamId);
|
||||
userIdParam.insert("name", "userId");
|
||||
userIdParam.insert("displayName", "User ID");
|
||||
userIdParam.insert("type", "QString");
|
||||
|
||||
QVariantMap endpointIdParam;
|
||||
endpointIdParam.insert("id", cloudNotificationsDeviceClassEndpointParamId);
|
||||
endpointIdParam.insert("name", "endpoint");
|
||||
endpointIdParam.insert("displayName", "Device");
|
||||
endpointIdParam.insert("type", "QString");
|
||||
|
||||
QVariantList cloudNotificationDeviceClassParamTypes;
|
||||
cloudNotificationDeviceClassParamTypes.append(userIdParam);
|
||||
cloudNotificationDeviceClassParamTypes.append(endpointIdParam);
|
||||
|
||||
QVariantMap notifyActionParamTitle;
|
||||
notifyActionParamTitle.insert("id", notifyActionParamTitleId);
|
||||
notifyActionParamTitle.insert("name", "title");
|
||||
notifyActionParamTitle.insert("displayName", "Title");
|
||||
notifyActionParamTitle.insert("type", "QString");
|
||||
|
||||
QVariantMap notifyActionParamBody;
|
||||
notifyActionParamBody.insert("id", notifyActionParamBodyId);
|
||||
notifyActionParamBody.insert("name", "body");
|
||||
notifyActionParamBody.insert("displayName", "Message text");
|
||||
notifyActionParamBody.insert("type", "QString");
|
||||
|
||||
QVariantList notifyActionParamTypes;
|
||||
notifyActionParamTypes.append(notifyActionParamTitle);
|
||||
notifyActionParamTypes.append(notifyActionParamBody);
|
||||
|
||||
QVariantMap notifyAction;
|
||||
notifyAction.insert("id", notifyActionTypeId);
|
||||
notifyAction.insert("name", "notify");
|
||||
notifyAction.insert("displayName", "Send notification");
|
||||
notifyAction.insert("paramTypes", notifyActionParamTypes);
|
||||
|
||||
QVariantList actionTypes;
|
||||
actionTypes.append(notifyAction);
|
||||
|
||||
QVariantMap connectedState;
|
||||
connectedState.insert("id", connectedStateTypeId);
|
||||
connectedState.insert("name", "connected");
|
||||
connectedState.insert("displayName", "connected");
|
||||
connectedState.insert("type", "bool");
|
||||
connectedState.insert("displayNameEvent", "Connected changed");
|
||||
connectedState.insert("defaultValue", false);
|
||||
|
||||
QVariantList stateTypes;
|
||||
stateTypes.append(connectedState);
|
||||
|
||||
|
||||
QVariantMap cloudNotificationsDeviceClass;
|
||||
cloudNotificationsDeviceClass.insert("id", cloudNotificationsDeviceClassId);
|
||||
cloudNotificationsDeviceClass.insert("name", "cloudNotifications");
|
||||
cloudNotificationsDeviceClass.insert("displayName", "Cloud Notifications");
|
||||
cloudNotificationsDeviceClass.insert("createMethods", createMethods);
|
||||
cloudNotificationsDeviceClass.insert("paramTypes", cloudNotificationDeviceClassParamTypes);
|
||||
cloudNotificationsDeviceClass.insert("interfaces", interfaces);
|
||||
cloudNotificationsDeviceClass.insert("actionTypes", actionTypes);
|
||||
cloudNotificationsDeviceClass.insert("stateTypes", stateTypes);
|
||||
|
||||
QVariantList deviceClasses;
|
||||
deviceClasses.append(cloudNotificationsDeviceClass);
|
||||
|
||||
QVariantMap guhVendor;
|
||||
guhVendor.insert("id", "2062d64d-3232-433c-88bc-0d33c0ba2ba6"); // guh's id
|
||||
guhVendor.insert("name", "guh");
|
||||
guhVendor.insert("displayName", "guh");
|
||||
guhVendor.insert("deviceClasses", deviceClasses);
|
||||
|
||||
QVariantList vendors;
|
||||
vendors.append(guhVendor);
|
||||
pluginMetaData.insert("vendors", vendors);
|
||||
return QJsonObject::fromVariantMap(pluginMetaData);
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus CloudNotifications::setupDevice(Device *device)
|
||||
{
|
||||
qWarning() << "--------------------------------------------------------------------- setupDevice" << device->id() << device->name();
|
||||
Q_UNUSED(device)
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
void CloudNotifications::startMonitoringAutoDevices()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError CloudNotifications::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
qCDebug(dcCloud()) << "executeAction" << device << action.id() << action.params();
|
||||
QString userId = device->paramValue(cloudNotificationsDeviceClassUserParamId).toString();
|
||||
QString endpointId = device->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString();
|
||||
int id = m_awsConnector->sendPushNotification(userId, endpointId, action.param(notifyActionParamTitleId).value().toString(), action.param(notifyActionParamBodyId).value().toString());
|
||||
m_pendingPushNotifications.insert(id, action.id());
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
|
||||
void CloudNotifications::pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints)
|
||||
{
|
||||
qCDebug(dcCloud()) << "Push Notification endpoint update";
|
||||
QList<Device*> devicesToRemove;
|
||||
foreach (Device *configuredDevice, myDevices()) {
|
||||
bool found = false;
|
||||
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
|
||||
if (configuredDevice->paramValue(cloudNotificationsDeviceClassUserParamId).toString() == ep.userId
|
||||
&& configuredDevice->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString() == ep.endpointId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
devicesToRemove.append(configuredDevice);
|
||||
}
|
||||
}
|
||||
foreach (Device *d, devicesToRemove) {
|
||||
emit autoDeviceDisappeared(d->id());
|
||||
}
|
||||
|
||||
QList<DeviceDescriptor> devicesToAdd;
|
||||
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
|
||||
bool found = false;
|
||||
foreach (Device *d, myDevices()) {
|
||||
if (d->paramValue(cloudNotificationsDeviceClassUserParamId).toString() == ep.userId
|
||||
&& d->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString() == ep.endpointId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
qCDebug(dcCloud) << "Adding new notification device" << ep.displayName;
|
||||
DeviceDescriptor descriptor(cloudNotificationsDeviceClassId, ep.displayName, QString("Send notifications to %1").arg(ep.displayName));
|
||||
ParamList params;
|
||||
Param userIdParam(cloudNotificationsDeviceClassUserParamId, ep.userId);
|
||||
params.append(userIdParam);
|
||||
Param endpointIdParam(cloudNotificationsDeviceClassEndpointParamId, ep.endpointId);
|
||||
params.append(endpointIdParam);
|
||||
descriptor.setParams(params);
|
||||
devicesToAdd.append(descriptor);
|
||||
}
|
||||
}
|
||||
emit autoDevicesAppeared(cloudNotificationsDeviceClassId, devicesToAdd);
|
||||
|
||||
}
|
||||
|
||||
void CloudNotifications::pushNotificationSent(int id, int status)
|
||||
{
|
||||
qCDebug(dcCloud()) << "Push notification sent" << id << status;
|
||||
ActionId actionId = m_pendingPushNotifications.value(id);
|
||||
emit actionExecutionFinished(actionId, status == 200 ? DeviceManager::DeviceErrorNoError : DeviceManager::DeviceErrorHardwareNotAvailable);
|
||||
}
|
||||
52
libguh-core/cloudnotifications.h
Normal file
52
libguh-core/cloudnotifications.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2017 Michael Zanetti <michael.zanetti@guh.io> *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* Guh is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* Guh is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef CLOUDNOTIFICATIONS_H
|
||||
#define CLOUDNOTIFICATIONS_H
|
||||
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "awsconnector.h"
|
||||
|
||||
class CloudNotifications : public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "deviceplugincloudnotifications.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
CloudNotifications(AWSConnector *awsConnector, QObject* parent = nullptr);
|
||||
|
||||
QJsonObject metaData() const;
|
||||
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void startMonitoringAutoDevices() override;
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
private slots:
|
||||
void pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints);
|
||||
void pushNotificationSent(int id, int status);
|
||||
|
||||
private:
|
||||
AWSConnector *m_awsConnector = nullptr;
|
||||
QHash<int, ActionId> m_pendingPushNotifications;
|
||||
};
|
||||
|
||||
#endif // CLOUDNOTIFICATIONS_H
|
||||
@ -103,6 +103,7 @@
|
||||
|
||||
#include "devicemanager.h"
|
||||
#include "plugin/device.h"
|
||||
#include "cloudnotifications.h"
|
||||
|
||||
namespace guhserver {
|
||||
|
||||
@ -506,6 +507,9 @@ void GuhCore::init() {
|
||||
m_cloudManager->setClientCertificates(m_configuration->cloudCertificateCA(), m_configuration->cloudCertificate(), m_configuration->cloudCertificateKey());
|
||||
m_cloudManager->setEnabled(m_configuration->cloudEnabled());
|
||||
|
||||
CloudNotifications *cloudNotifications = m_cloudManager->createNotificationsPlugin();
|
||||
m_deviceManager->registerStaticPlugin(cloudNotifications, cloudNotifications->metaData());
|
||||
|
||||
connect(m_configuration, &GuhConfiguration::localeChanged, this, &GuhCore::onLocaleChanged);
|
||||
connect(m_configuration, &GuhConfiguration::cloudEnabledChanged, m_cloudManager, &CloudManager::setEnabled);
|
||||
connect(m_configuration, &GuhConfiguration::serverNameChanged, m_cloudManager, &CloudManager::setDeviceName);
|
||||
|
||||
@ -73,6 +73,7 @@ HEADERS += guhcore.h \
|
||||
certificategenerator.h \
|
||||
awsconnector.h \
|
||||
cloudmanager.h \
|
||||
cloudnotifications.h \
|
||||
MbedTLS/MbedTLSConnection.hpp \
|
||||
janusconnector.h \
|
||||
pushbuttondbusservice.h \
|
||||
@ -96,7 +97,6 @@ HEADERS += guhcore.h \
|
||||
hardware/network/avahi/qtavahiservicebrowserimplementation.h \
|
||||
hardware/network/avahi/qtavahiservicebrowserimplementation_p.h \
|
||||
|
||||
|
||||
SOURCES += guhcore.cpp \
|
||||
tcpserver.cpp \
|
||||
mocktcpserver.cpp \
|
||||
@ -151,6 +151,7 @@ SOURCES += guhcore.cpp \
|
||||
certificategenerator.cpp \
|
||||
awsconnector.cpp \
|
||||
cloudmanager.cpp \
|
||||
cloudnotifications.cpp \
|
||||
MbedTLS/MbedTLSConnection.cpp \
|
||||
janusconnector.cpp \
|
||||
pushbuttondbusservice.cpp \
|
||||
|
||||
@ -208,7 +208,12 @@ DeviceManager::~DeviceManager()
|
||||
}
|
||||
|
||||
foreach (DevicePlugin *plugin, m_devicePlugins) {
|
||||
delete plugin;
|
||||
if (plugin->parent() == this) {
|
||||
qCDebug(dcDeviceManager()) << "Deleting plugin" << plugin->pluginName();
|
||||
delete plugin;
|
||||
} else {
|
||||
qCDebug(dcDeviceManager()) << "Not deleting plugin" << plugin->pluginName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,6 +259,19 @@ QList<QJsonObject> DeviceManager::pluginsMetadata()
|
||||
return pluginList;
|
||||
}
|
||||
|
||||
/*! Register a DevicePlugin class. This can be used to create devices internally from the guh system without having to create a full plugin.
|
||||
The DeviceManager takes ownership of the object and will clean it up when exiting. Do not delete the object yourself. */
|
||||
void DeviceManager::registerStaticPlugin(DevicePlugin *plugin, const QJsonObject &metaData)
|
||||
{
|
||||
if (!verifyPluginMetadata(metaData)) {
|
||||
qCWarning(dcDeviceManager()) << "Failed to verify plugin metadata. Not loading static plugin:" << plugin->pluginName();
|
||||
return;
|
||||
}
|
||||
plugin->setParent(this);
|
||||
plugin->setMetaData(metaData);
|
||||
loadPlugin(plugin);
|
||||
}
|
||||
|
||||
/*! Set the \a locale of all plugins and reload the translated strings. */
|
||||
void DeviceManager::setLocale(const QLocale &locale)
|
||||
{
|
||||
@ -1014,75 +1032,81 @@ void DeviceManager::loadPlugins()
|
||||
qCWarning(dcDeviceManager) << "Could not get plugin instance of" << entry;
|
||||
continue;
|
||||
}
|
||||
pluginIface->setParent(this);
|
||||
|
||||
if (!verifyPluginMetadata(loader.metaData().value("MetaData").toObject()))
|
||||
continue;
|
||||
|
||||
pluginIface->setMetaData(loader.metaData().value("MetaData").toObject());
|
||||
|
||||
pluginIface->setLocale(m_locale);
|
||||
qApp->installTranslator(pluginIface->translator());
|
||||
|
||||
pluginIface->initPlugin(this);
|
||||
|
||||
qCDebug(dcDeviceManager) << "**** Loaded plugin" << pluginIface->pluginName();
|
||||
foreach (const Vendor &vendor, pluginIface->supportedVendors()) {
|
||||
qCDebug(dcDeviceManager) << "* Loaded vendor:" << vendor.name();
|
||||
if (m_supportedVendors.contains(vendor.id()))
|
||||
continue;
|
||||
|
||||
m_supportedVendors.insert(vendor.id(), vendor);
|
||||
}
|
||||
|
||||
foreach (const DeviceClass &deviceClass, pluginIface->supportedDevices()) {
|
||||
if (!m_supportedVendors.contains(deviceClass.vendorId())) {
|
||||
qCWarning(dcDeviceManager) << "Vendor not found. Ignoring device. VendorId:" << deviceClass.vendorId() << "DeviceClass:" << deviceClass.name() << deviceClass.id();
|
||||
continue;
|
||||
}
|
||||
m_vendorDeviceMap[deviceClass.vendorId()].append(deviceClass.id());
|
||||
m_supportedDevices.insert(deviceClass.id(), deviceClass);
|
||||
qCDebug(dcDeviceManager) << "* Loaded device class:" << deviceClass.name();
|
||||
}
|
||||
|
||||
GuhSettings settings(GuhSettings::SettingsRolePlugins);
|
||||
settings.beginGroup("PluginConfig");
|
||||
ParamList params;
|
||||
if (settings.childGroups().contains(pluginIface->pluginId().toString())) {
|
||||
settings.beginGroup(pluginIface->pluginId().toString());
|
||||
foreach (const QString ¶mTypeIdString, settings.allKeys()) {
|
||||
Param param(ParamTypeId(paramTypeIdString), settings.value(paramTypeIdString));
|
||||
params.append(param);
|
||||
}
|
||||
settings.endGroup();
|
||||
} else if (!pluginIface->configurationDescription().isEmpty()){
|
||||
// plugin requires config but none stored. Init with defaults
|
||||
foreach (const ParamType ¶mType, pluginIface->configurationDescription()) {
|
||||
Param param(paramType.id(), paramType.defaultValue());
|
||||
params.append(param);
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
if (params.count() > 0) {
|
||||
DeviceError status = pluginIface->setConfiguration(params);
|
||||
if (status != DeviceErrorNoError) {
|
||||
qCWarning(dcDeviceManager) << "Error setting params to plugin. Broken configuration?";
|
||||
}
|
||||
}
|
||||
|
||||
m_devicePlugins.insert(pluginIface->pluginId(), pluginIface);
|
||||
|
||||
connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::eventTriggered);
|
||||
connect(pluginIface, &DevicePlugin::devicesDiscovered, this, &DeviceManager::slotDevicesDiscovered, Qt::QueuedConnection);
|
||||
connect(pluginIface, &DevicePlugin::deviceSetupFinished, this, &DeviceManager::slotDeviceSetupFinished);
|
||||
connect(pluginIface, &DevicePlugin::actionExecutionFinished, this, &DeviceManager::actionExecutionFinished);
|
||||
connect(pluginIface, &DevicePlugin::pairingFinished, this, &DeviceManager::slotPairingFinished);
|
||||
connect(pluginIface, &DevicePlugin::autoDevicesAppeared, this, &DeviceManager::onAutoDevicesAppeared);
|
||||
connect(pluginIface, &DevicePlugin::autoDeviceDisappeared, this, &DeviceManager::onAutoDeviceDisappeared);
|
||||
loadPlugin(pluginIface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::loadPlugin(DevicePlugin *pluginIface)
|
||||
{
|
||||
pluginIface->setLocale(m_locale);
|
||||
qApp->installTranslator(pluginIface->translator());
|
||||
|
||||
pluginIface->initPlugin(this);
|
||||
|
||||
qCDebug(dcDeviceManager) << "**** Loaded plugin" << pluginIface->pluginName();
|
||||
foreach (const Vendor &vendor, pluginIface->supportedVendors()) {
|
||||
qCDebug(dcDeviceManager) << "* Loaded vendor:" << vendor.name();
|
||||
if (m_supportedVendors.contains(vendor.id()))
|
||||
continue;
|
||||
|
||||
m_supportedVendors.insert(vendor.id(), vendor);
|
||||
}
|
||||
|
||||
foreach (const DeviceClass &deviceClass, pluginIface->supportedDevices()) {
|
||||
if (!m_supportedVendors.contains(deviceClass.vendorId())) {
|
||||
qCWarning(dcDeviceManager) << "Vendor not found. Ignoring device. VendorId:" << deviceClass.vendorId() << "DeviceClass:" << deviceClass.name() << deviceClass.id();
|
||||
continue;
|
||||
}
|
||||
m_vendorDeviceMap[deviceClass.vendorId()].append(deviceClass.id());
|
||||
m_supportedDevices.insert(deviceClass.id(), deviceClass);
|
||||
qCDebug(dcDeviceManager) << "* Loaded device class:" << deviceClass.name();
|
||||
}
|
||||
|
||||
GuhSettings settings(GuhSettings::SettingsRolePlugins);
|
||||
settings.beginGroup("PluginConfig");
|
||||
ParamList params;
|
||||
if (settings.childGroups().contains(pluginIface->pluginId().toString())) {
|
||||
settings.beginGroup(pluginIface->pluginId().toString());
|
||||
foreach (const QString ¶mTypeIdString, settings.allKeys()) {
|
||||
Param param(ParamTypeId(paramTypeIdString), settings.value(paramTypeIdString));
|
||||
params.append(param);
|
||||
}
|
||||
settings.endGroup();
|
||||
} else if (!pluginIface->configurationDescription().isEmpty()){
|
||||
// plugin requires config but none stored. Init with defaults
|
||||
foreach (const ParamType ¶mType, pluginIface->configurationDescription()) {
|
||||
Param param(paramType.id(), paramType.defaultValue());
|
||||
params.append(param);
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
if (params.count() > 0) {
|
||||
DeviceError status = pluginIface->setConfiguration(params);
|
||||
if (status != DeviceErrorNoError) {
|
||||
qCWarning(dcDeviceManager) << "Error setting params to plugin. Broken configuration?";
|
||||
}
|
||||
}
|
||||
|
||||
m_devicePlugins.insert(pluginIface->pluginId(), pluginIface);
|
||||
|
||||
connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::eventTriggered);
|
||||
connect(pluginIface, &DevicePlugin::devicesDiscovered, this, &DeviceManager::slotDevicesDiscovered, Qt::QueuedConnection);
|
||||
connect(pluginIface, &DevicePlugin::deviceSetupFinished, this, &DeviceManager::slotDeviceSetupFinished);
|
||||
connect(pluginIface, &DevicePlugin::actionExecutionFinished, this, &DeviceManager::actionExecutionFinished);
|
||||
connect(pluginIface, &DevicePlugin::pairingFinished, this, &DeviceManager::slotPairingFinished);
|
||||
connect(pluginIface, &DevicePlugin::autoDevicesAppeared, this, &DeviceManager::onAutoDevicesAppeared);
|
||||
connect(pluginIface, &DevicePlugin::autoDeviceDisappeared, this, &DeviceManager::onAutoDeviceDisappeared);
|
||||
}
|
||||
|
||||
void DeviceManager::loadConfiguredDevices()
|
||||
{
|
||||
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
||||
@ -1324,7 +1348,7 @@ void DeviceManager::onAutoDevicesAppeared(const DeviceClassId &deviceClassId, co
|
||||
foreach (const DeviceDescriptor &deviceDescriptor, deviceDescriptors) {
|
||||
Device *device = new Device(plugin->pluginId(), deviceClassId, this);
|
||||
device->m_autoCreated = true;
|
||||
device->setName(deviceClass.name());
|
||||
device->setName(deviceDescriptor.title());
|
||||
device->setParams(deviceDescriptor.params());
|
||||
|
||||
DeviceSetupStatus setupStatus = setupDevice(device);
|
||||
|
||||
@ -95,6 +95,7 @@ public:
|
||||
|
||||
static QStringList pluginSearchDirs();
|
||||
static QList<QJsonObject> pluginsMetadata();
|
||||
void registerStaticPlugin(DevicePlugin* plugin, const QJsonObject &metaData);
|
||||
|
||||
void setLocale(const QLocale &locale);
|
||||
|
||||
@ -158,6 +159,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void loadPlugins();
|
||||
void loadPlugin(DevicePlugin *pluginIface);
|
||||
void loadConfiguredDevices();
|
||||
void storeConfiguredDevices();
|
||||
void startMonitoringAutoDevices();
|
||||
|
||||
Reference in New Issue
Block a user