Merge PR #614: Allow running discoveries by interface

This commit is contained in:
Jenkins nymea 2021-07-05 16:50:21 +02:00
commit f6bc561f61
2 changed files with 72 additions and 21 deletions

View File

@ -32,6 +32,10 @@
#include "engine.h" #include "engine.h"
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcThingManager)
ThingDiscovery::ThingDiscovery(QObject *parent) : ThingDiscovery::ThingDiscovery(QObject *parent) :
QAbstractListModel(parent) QAbstractListModel(parent)
{ {
@ -71,31 +75,49 @@ QHash<int, QByteArray> ThingDiscovery::roleNames() const
void ThingDiscovery::discoverThings(const QUuid &thingClassId, const QVariantList &discoveryParams) void ThingDiscovery::discoverThings(const QUuid &thingClassId, const QVariantList &discoveryParams)
{ {
if (m_busy) {
qWarning() << "Busy... not restarting discovery";
return;
}
beginResetModel(); beginResetModel();
m_foundThings.clear(); m_foundThings.clear();
endResetModel(); endResetModel();
emit countChanged(); emit countChanged();
if (!m_engine) { if (!m_engine) {
qWarning() << "Cannot discover things. No Engine set"; qCWarning(dcThingManager()) << "Cannot discover things. No Engine set";
return; return;
} }
if (!m_engine->jsonRpcClient()->connected()) { if (!m_engine->jsonRpcClient()->connected()) {
qWarning() << "Cannot discover things. Not connected."; qCWarning(dcThingManager()) << "Cannot discover things. Not connected.";
return; return;
} }
QVariantMap params; discoverThingsInternal(thingClassId, discoveryParams);
params.insert("thingClassId", thingClassId.toString()); m_displayMessage.clear();
if (!discoveryParams.isEmpty()) { emit busyChanged();
params.insert("discoveryParams", discoveryParams); }
void ThingDiscovery::discoverThingsByInterface(const QString &interfaceName)
{
beginResetModel();
m_foundThings.clear();
endResetModel();
emit countChanged();
if (!m_engine) {
qCWarning(dcThingManager()) << "Cannot discover things. No Engine set";
return;
} }
m_engine->jsonRpcClient()->sendCommand("Integrations.DiscoverThings", params, this, "discoverThingsResponse"); if (!m_engine->jsonRpcClient()->connected()) {
m_busy = true; qCWarning(dcThingManager()) << "Cannot discover things. Not connected.";
return;
}
for (int i = 0; i < m_engine->thingManager()->thingClasses()->rowCount(); i++) {
ThingClass *thingClass = m_engine->thingManager()->thingClasses()->get(i);
if (!thingClass->interfaces().contains(interfaceName)) {
continue;
}
discoverThingsInternal(thingClass->id());
}
m_displayMessage.clear(); m_displayMessage.clear();
emit busyChanged(); emit busyChanged();
} }
@ -123,7 +145,7 @@ void ThingDiscovery::setEngine(Engine *engine)
bool ThingDiscovery::busy() const bool ThingDiscovery::busy() const
{ {
return m_busy; return !m_pendingRequests.isEmpty();
} }
QString ThingDiscovery::displayMessage() const QString ThingDiscovery::displayMessage() const
@ -131,14 +153,27 @@ QString ThingDiscovery::displayMessage() const
return m_displayMessage; return m_displayMessage;
} }
void ThingDiscovery::discoverThingsResponse(int /*commandId*/, const QVariantMap &params) void ThingDiscovery::discoverThingsInternal(const QUuid &thingClassId, const QVariantList &discoveryParams)
{ {
qDebug() << "Discovery response received" << params; qCDebug(dcThingManager()) << "Starting thing discovery for thing class" << m_engine->thingManager()->thingClasses()->getThingClass(thingClassId)->name() << thingClassId;
QVariantMap params;
params.insert("thingClassId", thingClassId.toString());
if (!discoveryParams.isEmpty()) {
params.insert("discoveryParams", discoveryParams);
}
int commandId = m_engine->jsonRpcClient()->sendCommand("Integrations.DiscoverThings", params, this, "discoverThingsResponse");
m_pendingRequests.append(commandId);
}
void ThingDiscovery::discoverThingsResponse(int commandId, const QVariantMap &params)
{
qCDebug(dcThingManager) << "Discovery response received" << params;
QVariantList descriptors = params.value("thingDescriptors").toList(); QVariantList descriptors = params.value("thingDescriptors").toList();
foreach (const QVariant &descriptorVariant, descriptors) { foreach (const QVariant &descriptorVariant, descriptors) {
if (!contains(descriptorVariant.toMap().value("id").toUuid())) { if (!contains(descriptorVariant.toMap().value("id").toUuid())) {
beginInsertRows(QModelIndex(), m_foundThings.count(), m_foundThings.count()); beginInsertRows(QModelIndex(), m_foundThings.count(), m_foundThings.count());
ThingDescriptor *descriptor = new ThingDescriptor(descriptorVariant.toMap().value("id").toUuid(), ThingDescriptor *descriptor = new ThingDescriptor(descriptorVariant.toMap().value("id").toUuid(),
descriptorVariant.toMap().value("thingClassId").toUuid(), // Note: This will only be provided as of nymea 0.28!
descriptorVariant.toMap().value("thingId").toString(), descriptorVariant.toMap().value("thingId").toString(),
descriptorVariant.toMap().value("title").toString(), descriptorVariant.toMap().value("title").toString(),
descriptorVariant.toMap().value("description").toString()); descriptorVariant.toMap().value("description").toString());
@ -154,16 +189,20 @@ void ThingDiscovery::discoverThingsResponse(int /*commandId*/, const QVariantMap
Param* p = new Param(paramVariant.toMap().value("paramTypeId").toString(), paramVariant.toMap().value("value")); Param* p = new Param(paramVariant.toMap().value("paramTypeId").toString(), paramVariant.toMap().value("value"));
descriptor->params()->addParam(p); descriptor->params()->addParam(p);
} }
qDebug() << "Found thing. Descriptor:" << descriptor->name() << descriptor->id(); qCDebug(dcThingManager()) << "Found thing. Descriptor:" << descriptor->name() << descriptor->id();
m_foundThings.append(descriptor); m_foundThings.append(descriptor);
endInsertRows(); endInsertRows();
emit countChanged(); emit countChanged();
} }
} }
// Note: in case of multiple discoveries we'll just overwrite the message... Not ideal but multiple error messages from different plugins
// wouldn't be of much use to the user anyways.
m_displayMessage = params.value("displayMessage").toString(); m_displayMessage = params.value("displayMessage").toString();
m_busy = false; m_pendingRequests.removeAll(commandId);
emit busyChanged(); if (m_pendingRequests.isEmpty()) {
emit busyChanged();
}
} }
bool ThingDiscovery::contains(const QUuid &deviceDescriptorId) const bool ThingDiscovery::contains(const QUuid &deviceDescriptorId) const
@ -176,9 +215,10 @@ bool ThingDiscovery::contains(const QUuid &deviceDescriptorId) const
return false; return false;
} }
ThingDescriptor::ThingDescriptor(const QUuid &id, const QUuid &thingId, const QString &name, const QString &description, QObject *parent): ThingDescriptor::ThingDescriptor(const QUuid &id, const QUuid &thingClassId, const QUuid &thingId, const QString &name, const QString &description, QObject *parent):
QObject(parent), QObject(parent),
m_id(id), m_id(id),
m_thingClassId(thingClassId),
m_thingId(thingId), m_thingId(thingId),
m_name(name), m_name(name),
m_description(description), m_description(description),
@ -192,6 +232,11 @@ QUuid ThingDescriptor::id() const
return m_id; return m_id;
} }
QUuid ThingDescriptor::thingClassId() const
{
return m_thingClassId;
}
QUuid ThingDescriptor::thingId() const QUuid ThingDescriptor::thingId() const
{ {
return m_thingId; return m_thingId;

View File

@ -39,14 +39,16 @@
class ThingDescriptor: public QObject { class ThingDescriptor: public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QUuid id READ id CONSTANT) Q_PROPERTY(QUuid id READ id CONSTANT)
Q_PROPERTY(QUuid thingClassId READ thingClassId CONSTANT)
Q_PROPERTY(QUuid thingId READ thingId CONSTANT) Q_PROPERTY(QUuid thingId READ thingId CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT) Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(Params* params READ params CONSTANT) Q_PROPERTY(Params* params READ params CONSTANT)
public: public:
ThingDescriptor(const QUuid &id, const QUuid &thingId, const QString &name, const QString &description, QObject *parent = nullptr); ThingDescriptor(const QUuid &id, const QUuid &thingClassId, const QUuid &thingId, const QString &name, const QString &description, QObject *parent = nullptr);
QUuid id() const; QUuid id() const;
QUuid thingClassId() const;
QUuid thingId() const; QUuid thingId() const;
QString name() const; QString name() const;
QString description() const; QString description() const;
@ -54,6 +56,7 @@ public:
private: private:
QUuid m_id; QUuid m_id;
QUuid m_thingClassId;
QUuid m_thingId; QUuid m_thingId;
QString m_name; QString m_name;
QString m_description; QString m_description;
@ -83,6 +86,7 @@ public:
Q_INVOKABLE void discoverThings(const QUuid &thingClassId, const QVariantList &discoveryParams = {}); Q_INVOKABLE void discoverThings(const QUuid &thingClassId, const QVariantList &discoveryParams = {});
Q_INVOKABLE void discoverThingsByInterface(const QString &interfaceName);
Q_INVOKABLE ThingDescriptor* get(int index) const; Q_INVOKABLE ThingDescriptor* get(int index) const;
@ -93,6 +97,8 @@ public:
QString displayMessage() const; QString displayMessage() const;
private slots: private slots:
void discoverThingsInternal(const QUuid &thingClassId, const QVariantList &discoveryParams = {});
void discoverThingsResponse(int commandId, const QVariantMap &params); void discoverThingsResponse(int commandId, const QVariantMap &params);
signals: signals:
@ -102,8 +108,8 @@ signals:
private: private:
Engine *m_engine = nullptr; Engine *m_engine = nullptr;
bool m_busy = false;
QString m_displayMessage; QString m_displayMessage;
QList<int> m_pendingRequests;
bool contains(const QUuid &deviceDescriptorId) const; bool contains(const QUuid &deviceDescriptorId) const;
QList<ThingDescriptor*> m_foundThings; QList<ThingDescriptor*> m_foundThings;