mirror of https://github.com/nymea/nymea.git
More work on adding a Device browser
parent
933d92ab06
commit
57f68bcdc0
|
|
@ -710,12 +710,40 @@ Device::DeviceError DeviceManagerImplementation::removeConfiguredDevice(const De
|
|||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
BrowserItems DeviceManagerImplementation::browseDevice(const DeviceId &deviceId, const QString &browser, const BrowserItemId &node)
|
||||
Device::BrowseResult DeviceManagerImplementation::browseDevice(const DeviceId &deviceId, const QString &nodeId)
|
||||
{
|
||||
Q_UNUSED(deviceId)
|
||||
Q_UNUSED(browser)
|
||||
Q_UNUSED(node)
|
||||
return BrowserItems();
|
||||
Q_UNUSED(nodeId)
|
||||
|
||||
Device::BrowseResult result = createBrowseResult();
|
||||
|
||||
Device *device = m_configuredDevices.value(deviceId);
|
||||
if (!device) {
|
||||
qCWarning(dcDeviceManager()) << "Cannot browse device. No such device:" << deviceId.toString();
|
||||
result.status = Device::DeviceErrorDeviceNotFound;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!device->deviceClass().browsable()) {
|
||||
qCWarning(dcDeviceManager()) << "Cannot browse device. DeviceClass" << device->deviceClass().name() << "is not browsable.";
|
||||
result.status = Device::DeviceErrorUnsupportedFeature;
|
||||
return result;
|
||||
}
|
||||
|
||||
result = device->plugin()->browseDevice(device, result, nodeId);
|
||||
return result;
|
||||
}
|
||||
|
||||
Device::DeviceError DeviceManagerImplementation::executeBrowserItem(const DeviceId &deviceId, const QString &nodeId)
|
||||
{
|
||||
Device *device = m_configuredDevices.value(deviceId);
|
||||
if (!device) {
|
||||
return Device::DeviceErrorDeviceNotFound;
|
||||
}
|
||||
if (!device->deviceClass().browsable()) {
|
||||
return Device::DeviceErrorUnsupportedFeature;
|
||||
}
|
||||
return device->plugin()->executeBrowserItem(device, nodeId);
|
||||
}
|
||||
|
||||
QString DeviceManagerImplementation::translate(const PluginId &pluginId, const QString &string, const QLocale &locale)
|
||||
|
|
@ -980,6 +1008,7 @@ void DeviceManagerImplementation::loadPlugin(DevicePlugin *pluginIface, const Pl
|
|||
connect(pluginIface, &DevicePlugin::pairingFinished, this, &DeviceManagerImplementation::slotPairingFinished);
|
||||
connect(pluginIface, &DevicePlugin::autoDevicesAppeared, this, &DeviceManagerImplementation::onAutoDevicesAppeared);
|
||||
connect(pluginIface, &DevicePlugin::autoDeviceDisappeared, this, &DeviceManagerImplementation::onAutoDeviceDisappeared);
|
||||
connect(pluginIface, &DevicePlugin::browseRequestFinished, this, &DeviceManagerImplementation::browseRequestFinished);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ public:
|
|||
|
||||
Device::DeviceError removeConfiguredDevice(const DeviceId &deviceId) override;
|
||||
|
||||
BrowserItems browseDevice(const DeviceId &deviceId, const QString &browser, const BrowserItemId &node = BrowserItemId()) override;
|
||||
Device::BrowseResult browseDevice(const DeviceId &deviceId, const QString &nodeId = QString()) override;
|
||||
Device::DeviceError executeBrowserItem(const DeviceId &deviceId, const QString &nodeId) override;
|
||||
|
||||
QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -283,6 +283,23 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||
returns.insert("o:values", states);
|
||||
setReturns("GetStateValues", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("BrowseDevice", "Browse a device. If a DeviceClass indicates a device is browsable, this method will return the BrowserItems. If no parameter besides the deviceId is used, the root node of this device will be returned. Any returned item which is browsable can be passed as node. Results will be children of the given node.");
|
||||
params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("o:nodeId", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
setParams("BrowseDevice", params);
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorRef());
|
||||
returns.insert("items", QVariantList() << JsonTypes::browserItemRef());
|
||||
setReturns("BrowseDevice", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("ExecuteBrowserItem", "Execute the item identified by nodeId on the given device.");
|
||||
params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("o:nodeId", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
setParams("ExecuteBrowserItem", params);
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorRef());
|
||||
setReturns("ExecuteBrowserItem", returns);
|
||||
|
||||
// Notifications
|
||||
params.clear(); returns.clear();
|
||||
setDescription("StateChanged", "Emitted whenever a State of a device changes.");
|
||||
|
|
@ -329,6 +346,7 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||
connect(NymeaCore::instance(), &NymeaCore::deviceSetupFinished, this, &DeviceHandler::deviceSetupFinished);
|
||||
connect(NymeaCore::instance(), &NymeaCore::deviceReconfigurationFinished, this, &DeviceHandler::deviceReconfigurationFinished);
|
||||
connect(NymeaCore::instance(), &NymeaCore::pairingFinished, this, &DeviceHandler::pairingFinished);
|
||||
connect(NymeaCore::instance()->deviceManager(), &DeviceManager::browseRequestFinished, this, &DeviceHandler::browseRequestFinished);
|
||||
}
|
||||
|
||||
/*! Returns the name of the \l{DeviceHandler}. In this case \b Devices.*/
|
||||
|
|
@ -669,14 +687,31 @@ JsonReply *DeviceHandler::BrowseDevice(const QVariantMap ¶ms) const
|
|||
{
|
||||
QVariantMap returns;
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QString browser = params.value("browser").toString();
|
||||
QString nodeId = params.value("nodeId").toString();
|
||||
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(deviceId);
|
||||
if (!device) {
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorToString(Device::DeviceErrorDeviceNotFound));
|
||||
return createReply(returns);
|
||||
Device::BrowseResult result = NymeaCore::instance()->deviceManager()->browseDevice(deviceId, nodeId);
|
||||
|
||||
if (result.status == Device::DeviceErrorAsync ) {
|
||||
JsonReply *reply = createAsyncReply("BrowseDevice");
|
||||
m_asyncBrowseRequests.insert(result.id, reply);
|
||||
connect(reply, &JsonReply::finished, this, [this, result](){
|
||||
m_asyncBrowseRequests.remove(result.id);
|
||||
});
|
||||
return reply;
|
||||
}
|
||||
NymeaCore::instance()->deviceManager()->browseDevice(device->id(), browser);
|
||||
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorToString(result.status));
|
||||
returns.insert("items", JsonTypes::packBrowserItems(result.items));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *DeviceHandler::ExecuteBrowserItem(const QVariantMap ¶ms)
|
||||
{
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QString nodeId = params.value("nodeId").toString();
|
||||
Device::DeviceError status = NymeaCore::instance()->deviceManager()->executeBrowserItem(deviceId, nodeId);
|
||||
QVariantMap returns;
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorToString(status));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
|
|
@ -805,4 +840,18 @@ void DeviceHandler::pairingFinished(const PairingTransactionId &pairingTransacti
|
|||
m_asynDeviceAdditions.insert(deviceId, reply);
|
||||
}
|
||||
|
||||
void DeviceHandler::browseRequestFinished(const Device::BrowseResult &result)
|
||||
{
|
||||
if (!m_asyncBrowseRequests.contains(result.id)) {
|
||||
qCWarning(dcJsonRpc()) << "No pending JsonRpc reply. Did it time out?";
|
||||
return;
|
||||
}
|
||||
JsonReply *reply = m_asyncBrowseRequests.take(result.id);
|
||||
QVariantMap params;
|
||||
params.insert("deviceError", JsonTypes::deviceErrorToString(result.status));
|
||||
params.insert("items", JsonTypes::packBrowserItems(result.items));
|
||||
reply->setData(params);
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public:
|
|||
Q_INVOKABLE JsonReply *GetStateValues(const QVariantMap ¶ms) const;
|
||||
|
||||
Q_INVOKABLE JsonReply *BrowseDevice(const QVariantMap ¶ms) const;
|
||||
Q_INVOKABLE JsonReply *ExecuteBrowserItem(const QVariantMap ¶ms);
|
||||
|
||||
signals:
|
||||
void PluginConfigurationChanged(const QVariantMap ¶ms);
|
||||
|
|
@ -88,12 +89,15 @@ private slots:
|
|||
|
||||
void pairingFinished(const PairingTransactionId &pairingTransactionId, Device::DeviceError status, const DeviceId &deviceId);
|
||||
|
||||
void browseRequestFinished(const Device::BrowseResult &result);
|
||||
|
||||
private:
|
||||
// A cache for async replies
|
||||
mutable QHash<DeviceClassId, JsonReply*> m_discoverRequests;
|
||||
mutable QHash<DeviceId, JsonReply*> m_asynDeviceAdditions;
|
||||
mutable QHash<DeviceId, JsonReply*> m_asynDeviceEditAdditions;
|
||||
mutable QHash<QUuid, JsonReply*> m_asyncPairingRequests;
|
||||
mutable QHash<QUuid, JsonReply*> m_asyncBrowseRequests;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ QVariantMap JsonTypes::s_tag;
|
|||
QVariantMap JsonTypes::s_mqttPolicy;
|
||||
QVariantMap JsonTypes::s_package;
|
||||
QVariantMap JsonTypes::s_repository;
|
||||
QVariantMap JsonTypes::s_browserItem;
|
||||
|
||||
void JsonTypes::init()
|
||||
{
|
||||
|
|
@ -273,6 +274,7 @@ void JsonTypes::init()
|
|||
s_deviceClass.insert("name", basicTypeToString(String));
|
||||
s_deviceClass.insert("displayName", basicTypeToString(String));
|
||||
s_deviceClass.insert("interfaces", QVariantList() << basicTypeToString(String));
|
||||
s_deviceClass.insert("browsable", basicTypeToString(Bool));
|
||||
s_deviceClass.insert("setupMethod", setupMethodRef());
|
||||
s_deviceClass.insert("createMethods", QVariantList() << createMethodRef());
|
||||
s_deviceClass.insert("stateTypes", QVariantList() << stateTypeRef());
|
||||
|
|
@ -403,6 +405,7 @@ void JsonTypes::init()
|
|||
s_tag.insert("tagId", basicTypeToString(QVariant::String));
|
||||
s_tag.insert("o:value", basicTypeToString(QVariant::String));
|
||||
|
||||
// Package
|
||||
s_package.insert("id", basicTypeToString(QVariant::String));
|
||||
s_package.insert("displayName", basicTypeToString(QVariant::String));
|
||||
s_package.insert("summary", basicTypeToString(QVariant::String));
|
||||
|
|
@ -413,10 +416,19 @@ void JsonTypes::init()
|
|||
s_package.insert("rollbackAvailable", basicTypeToString(QVariant::Bool));
|
||||
s_package.insert("canRemove", basicTypeToString(QVariant::Bool));
|
||||
|
||||
// Repository
|
||||
s_repository.insert("id", basicTypeToString(QVariant::String));
|
||||
s_repository.insert("displayName", basicTypeToString(QVariant::String));
|
||||
s_repository.insert("enabled", basicTypeToString(QVariant::Bool));
|
||||
|
||||
// BrowserItem
|
||||
s_browserItem.insert("id", basicTypeToString(QVariant::String));
|
||||
s_browserItem.insert("displayName", basicTypeToString(QVariant::String));
|
||||
s_browserItem.insert("description", basicTypeToString(QVariant::String));
|
||||
s_browserItem.insert("thumbnail", basicTypeToString(QVariant::String));
|
||||
s_browserItem.insert("executable", basicTypeToString(QVariant::Bool));
|
||||
s_browserItem.insert("browsable", basicTypeToString(QVariant::Bool));
|
||||
|
||||
s_initialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -706,6 +718,18 @@ QVariantMap JsonTypes::packParam(const Param ¶m)
|
|||
return variantMap;
|
||||
}
|
||||
|
||||
QVariantMap JsonTypes::packBrowserItem(const BrowserItem &item)
|
||||
{
|
||||
QVariantMap ret;
|
||||
ret.insert("id", item.id());
|
||||
ret.insert("displayName", item.displayName());
|
||||
ret.insert("description", item.description());
|
||||
ret.insert("thumbnail", item.thumbnail());
|
||||
ret.insert("executable", item.executable());
|
||||
ret.insert("browsable", item.browsable());
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packParams(const ParamList ¶mList)
|
||||
{
|
||||
QVariantList ret;
|
||||
|
|
@ -790,6 +814,7 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass, const QLo
|
|||
variant.insert("vendorId", deviceClass.vendorId().toString());
|
||||
variant.insert("pluginId", deviceClass.pluginId().toString());
|
||||
variant.insert("interfaces", deviceClass.interfaces());
|
||||
variant.insert("browsable", deviceClass.browsable());
|
||||
|
||||
QVariantList stateTypes;
|
||||
foreach (const StateType &stateType, deviceClass.stateTypes())
|
||||
|
|
@ -1186,6 +1211,15 @@ QVariantList JsonTypes::packDeviceDescriptors(const QList<DeviceDescriptor> devi
|
|||
return deviceDescriptorList;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packBrowserItems(const BrowserItems &items)
|
||||
{
|
||||
QVariantList ret;
|
||||
foreach (const BrowserItem &item, items) {
|
||||
ret.append(packBrowserItem(item));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*! Returns a variant map with the current basic configuration of the server. */
|
||||
QVariantMap JsonTypes::packBasicConfiguration()
|
||||
{
|
||||
|
|
@ -2080,6 +2114,12 @@ QPair<bool, QString> JsonTypes::validateVariant(const QVariant &templateVariant,
|
|||
qCWarning(dcJsonRpc) << "Repository not matching";
|
||||
return result;
|
||||
}
|
||||
} else if (refName == browserItemRef()) {
|
||||
QPair<bool, QString> result = validateMap(browserItemDescription(), variant.toMap());
|
||||
if (!result.first) {
|
||||
qCWarning(dcJsonRpc) << "BrowserItem not matching";
|
||||
return result;
|
||||
}
|
||||
} else if (refName == basicTypeRef()) {
|
||||
QPair<bool, QString> result = validateBasicType(variant);
|
||||
if (!result.first) {
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public:
|
|||
DECLARE_OBJECT(mqttPolicy, "MqttPolicy")
|
||||
DECLARE_OBJECT(package, "Package")
|
||||
DECLARE_OBJECT(repository, "Repository")
|
||||
DECLARE_OBJECT(browserItem, "BrowserItem")
|
||||
|
||||
// pack types
|
||||
static QVariantMap packEventType(const EventType &eventType, const PluginId &pluginId, const QLocale &locale);
|
||||
|
|
@ -194,7 +195,7 @@ public:
|
|||
static QVariantMap packStateDescriptor(const StateDescriptor &stateDescriptor);
|
||||
static QVariantMap packStateEvaluator(const StateEvaluator &stateEvaluator);
|
||||
static QVariantMap packParam(const Param ¶m);
|
||||
static QVariantList packParams(const ParamList ¶mList);
|
||||
static QVariantMap packBrowserItem(const BrowserItem &item);
|
||||
static QVariantMap packParamType(const ParamType ¶mType, const PluginId &pluginId, const QLocale &locale);
|
||||
static QVariantMap packParamDescriptor(const ParamDescriptor ¶mDescriptor);
|
||||
static QVariantMap packVendor(const Vendor &vendor, const QLocale &locale);
|
||||
|
|
@ -214,6 +215,8 @@ public:
|
|||
static QVariantMap packWiredNetworkDevice(WiredNetworkDevice *networkDevice);
|
||||
static QVariantMap packWirelessNetworkDevice(WirelessNetworkDevice *networkDevice);
|
||||
|
||||
static QVariantList packParams(const ParamList ¶mList);
|
||||
static QVariantList packBrowserItems(const BrowserItems &items);
|
||||
static QVariantList packRules(const QList<Rule> rules);
|
||||
static QVariantList packCreateMethods(DeviceClass::CreateMethods createMethods);
|
||||
static QVariantList packSupportedVendors(const QLocale &locale);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,18 @@ PluginId Device::pluginId() const
|
|||
return m_plugin->pluginId();
|
||||
}
|
||||
|
||||
/*! Returns the \l{DeviceClass} of this device. */
|
||||
DeviceClass Device::deviceClass() const
|
||||
{
|
||||
return m_deviceClass;
|
||||
}
|
||||
|
||||
/*! Returns the the \l{DevicePlugin} this Device is managed by. */
|
||||
DevicePlugin *Device::plugin() const
|
||||
{
|
||||
return m_plugin;
|
||||
}
|
||||
|
||||
/*! Returns the name of this Device. This is visible to the user. */
|
||||
QString Device::name() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "types/deviceclass.h"
|
||||
#include "types/state.h"
|
||||
#include "types/param.h"
|
||||
#include "types/browseritem.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QUuid>
|
||||
|
|
@ -69,7 +70,8 @@ public:
|
|||
DeviceErrorDeviceInRule,
|
||||
DeviceErrorDeviceIsChild,
|
||||
DeviceErrorPairingTransactionIdNotFound,
|
||||
DeviceErrorParameterNotWritable
|
||||
DeviceErrorParameterNotWritable,
|
||||
DeviceErrorUnsupportedFeature,
|
||||
};
|
||||
Q_ENUM(DeviceError)
|
||||
|
||||
|
|
@ -80,12 +82,22 @@ public:
|
|||
};
|
||||
Q_ENUM(DeviceSetupStatus)
|
||||
|
||||
class BrowseResult {
|
||||
public:
|
||||
QUuid id;
|
||||
Device::DeviceError status = Device::DeviceErrorNoError;
|
||||
BrowserItems items;
|
||||
private:
|
||||
BrowseResult(): id(QUuid::createUuid()) {}
|
||||
friend class DeviceManager;
|
||||
};
|
||||
|
||||
DeviceId id() const;
|
||||
DeviceClassId deviceClassId() const;
|
||||
PluginId pluginId() const;
|
||||
|
||||
DeviceClass deviceClass() const;
|
||||
DevicePlugin* plugin();
|
||||
DevicePlugin* plugin() const;
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
|
|
|||
|
|
@ -39,3 +39,14 @@ DeviceManager::DeviceManager(QObject *parent) : QObject(parent)
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
Device::BrowseResult DeviceManager::createBrowseResult()
|
||||
{
|
||||
Device::BrowseResult result = Device::BrowseResult();
|
||||
return result;
|
||||
}
|
||||
|
||||
QUuid DeviceManager::browseResultId(const Device::BrowseResult &result)
|
||||
{
|
||||
return result.id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ public:
|
|||
|
||||
virtual Device::DeviceError removeConfiguredDevice(const DeviceId &deviceId) = 0;
|
||||
|
||||
virtual BrowserItems browseDevice(const DeviceId &deviceId, const QString &browser, const BrowserItemId &node = BrowserItemId()) = 0;
|
||||
virtual Device::BrowseResult browseDevice(const DeviceId &deviceId, const QString &nodeId = QString()) = 0;
|
||||
virtual Device::DeviceError executeBrowserItem(const DeviceId &deviceId, const QString &nodeId) = 0;
|
||||
|
||||
virtual QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) = 0;
|
||||
|
||||
|
|
@ -88,7 +89,11 @@ signals:
|
|||
void deviceReconfigurationFinished(Device *device, Device::DeviceError status);
|
||||
void pairingFinished(const PairingTransactionId &pairingTransactionId, Device::DeviceError status, const DeviceId &deviceId = DeviceId());
|
||||
void actionExecutionFinished(const ActionId &actionId, Device::DeviceError status);
|
||||
void browseRequestFinished(const Device::BrowseResult &result);
|
||||
|
||||
protected:
|
||||
Device::BrowseResult createBrowseResult();
|
||||
QUuid browseResultId(const Device::BrowseResult &result);
|
||||
};
|
||||
|
||||
#endif // DEVICEMANAGER_H
|
||||
|
|
|
|||
|
|
@ -248,6 +248,22 @@ Device::DeviceError DevicePlugin::executeAction(Device *device, const Action &ac
|
|||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePlugin::browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(nodeId)
|
||||
|
||||
result.status = Device::DeviceErrorUnsupportedFeature;
|
||||
return result;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePlugin::executeBrowserItem(Device *device, const QString &nodeId)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(nodeId)
|
||||
return Device::DeviceErrorUnsupportedFeature;
|
||||
}
|
||||
|
||||
/*! Returns the configuration description of this DevicePlugin as a list of \l{ParamType}{ParamTypes}. */
|
||||
ParamTypes DevicePlugin::configurationDescription() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ public:
|
|||
|
||||
virtual Device::DeviceError executeAction(Device *device, const Action &action);
|
||||
|
||||
virtual Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId = QString());
|
||||
virtual Device::DeviceError executeBrowserItem(Device *device, const QString &nodeId);
|
||||
|
||||
// Configuration
|
||||
ParamTypes configurationDescription() const;
|
||||
Device::DeviceError setConfiguration(const ParamList &configuration);
|
||||
|
|
@ -96,6 +99,7 @@ signals:
|
|||
void configValueChanged(const ParamTypeId ¶mTypeId, const QVariant &value);
|
||||
void autoDevicesAppeared(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> &deviceDescriptors);
|
||||
void autoDeviceDisappeared(const DeviceId &deviceId);
|
||||
void browseRequestFinished(const Device::BrowseResult &result);
|
||||
|
||||
protected:
|
||||
Devices myDevices() const;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
QJsonObject deviceClassObject = deviceClassJson.toObject();
|
||||
/*! Returns a list of all valid JSON properties a DeviceClass JSON definition can have. */
|
||||
QStringList deviceClassProperties = QStringList() << "id" << "name" << "displayName" << "createMethods" << "setupMethod"
|
||||
<< "interfaces" << "pairingInfo" << "discoveryParamTypes" << "discoveryParamTypes"
|
||||
<< "interfaces" << "browsable" << "pairingInfo" << "discoveryParamTypes" << "discoveryParamTypes"
|
||||
<< "paramTypes" << "settingsTypes" << "stateTypes" << "actionTypes" << "eventTypes";
|
||||
QStringList mandatoryDeviceClassProperties = QStringList() << "id" << "name" << "displayName";
|
||||
|
||||
|
|
@ -192,6 +192,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
DeviceClass deviceClass(pluginId(), vendorId, deviceClassId);
|
||||
deviceClass.setName(deviceClassName);
|
||||
deviceClass.setDisplayName(deviceClassObject.value("displayName").toString());
|
||||
deviceClass.setBrowsable(deviceClassObject.value("browsable").toBool());
|
||||
|
||||
// Read create methods
|
||||
DeviceClass::CreateMethods createMethods;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,70 @@
|
|||
#include "browseritem.h"
|
||||
|
||||
BrowserItem::BrowserItem()
|
||||
|
||||
BrowserItem::BrowserItem(const QString &id, const QString &displayName, bool browsable):
|
||||
m_id(id),
|
||||
m_displayName(displayName),
|
||||
m_browsable(browsable)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString BrowserItem::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
QString BrowserItem::displayName() const
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
|
||||
QString BrowserItem::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void BrowserItem::setDescription(const QString &description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
bool BrowserItem::executable() const
|
||||
{
|
||||
return m_executable;
|
||||
}
|
||||
|
||||
void BrowserItem::setExecutable(bool executable)
|
||||
{
|
||||
m_executable = executable;
|
||||
}
|
||||
|
||||
bool BrowserItem::browsable() const
|
||||
{
|
||||
return m_browsable;
|
||||
}
|
||||
|
||||
void BrowserItem::setBrowsable(bool browsable)
|
||||
{
|
||||
m_browsable = browsable;
|
||||
}
|
||||
|
||||
QString BrowserItem::thumbnail() const
|
||||
{
|
||||
return m_thumbnail;
|
||||
}
|
||||
|
||||
void BrowserItem::setThumbnail(const QString &thumbnail)
|
||||
{
|
||||
m_thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
BrowserItems::BrowserItems()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BrowserItems::BrowserItems(const QList<BrowserItem> &other): QList<BrowserItem>(other)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,41 @@
|
|||
class LIBNYMEA_EXPORT BrowserItem
|
||||
{
|
||||
public:
|
||||
BrowserItem();
|
||||
BrowserItem(const QString &id = QString(), const QString &displayName = QString(), bool browsable = false);
|
||||
|
||||
QString id() const;
|
||||
void setId(const QString &id);
|
||||
|
||||
QString displayName() const;
|
||||
void setDisplayName(const QString &displayName);
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString &description);
|
||||
|
||||
bool executable() const;
|
||||
void setExecutable(bool executable);
|
||||
|
||||
bool browsable() const;
|
||||
void setBrowsable(bool browsable);
|
||||
|
||||
QString thumbnail() const;
|
||||
void setThumbnail(const QString &thumbnail);
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_description;
|
||||
bool m_executable = false;
|
||||
bool m_browsable = false;
|
||||
QString m_thumbnail;
|
||||
};
|
||||
|
||||
|
||||
class LIBNYMEA_EXPORT BrowserItems: public QList<BrowserItem>
|
||||
{
|
||||
public:
|
||||
BrowserItems();
|
||||
BrowserItems(const QList<BrowserItem> &other);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -308,6 +308,16 @@ void DeviceClass::setInterfaces(const QStringList &interfaces)
|
|||
m_interfaces = interfaces;
|
||||
}
|
||||
|
||||
bool DeviceClass::browsable() const
|
||||
{
|
||||
return m_browsable;
|
||||
}
|
||||
|
||||
void DeviceClass::setBrowsable(bool browsable)
|
||||
{
|
||||
m_browsable = browsable;
|
||||
}
|
||||
|
||||
/*! Compare this \a deviceClass to another. This is effectively the same as calling a.id() == b.id(). Returns true if the ids match.*/
|
||||
bool DeviceClass::operator==(const DeviceClass &deviceClass) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ public:
|
|||
QStringList interfaces() const;
|
||||
void setInterfaces(const QStringList &interfaces);
|
||||
|
||||
bool browsable() const;
|
||||
void setBrowsable(bool browsable);
|
||||
|
||||
bool operator==(const DeviceClass &device) const;
|
||||
|
||||
private:
|
||||
|
|
@ -113,6 +116,7 @@ private:
|
|||
PluginId m_pluginId;
|
||||
QString m_name;
|
||||
QString m_displayName;
|
||||
bool m_browsable = false;
|
||||
StateTypes m_stateTypes;
|
||||
EventTypes m_eventTypes;
|
||||
ActionTypes m_actionTypes;
|
||||
|
|
|
|||
|
|
@ -57,11 +57,10 @@ DECLARE_TYPE_ID(ActionType)
|
|||
DECLARE_TYPE_ID(Action)
|
||||
DECLARE_TYPE_ID(Plugin)
|
||||
DECLARE_TYPE_ID(Rule)
|
||||
DECLARE_TYPE_ID(Browser)
|
||||
|
||||
DECLARE_TYPE_ID(PairingTransaction)
|
||||
|
||||
DECLARE_TYPE_ID(BrowserItem)
|
||||
|
||||
class LIBNYMEA_EXPORT Types
|
||||
{
|
||||
Q_GADGET
|
||||
|
|
@ -153,6 +152,10 @@ public:
|
|||
};
|
||||
Q_ENUM(StateOperator)
|
||||
|
||||
enum BrowserType {
|
||||
BrowserTypeGeneric,
|
||||
};
|
||||
Q_ENUM(BrowserType)
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Types::InputType)
|
||||
|
|
|
|||
|
|
@ -239,6 +239,30 @@ Device::DeviceError DevicePluginMock::displayPin(const PairingTransactionId &pai
|
|||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePluginMock::browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId)
|
||||
{
|
||||
qCDebug(dcMockDevice()) << "Browse device called" << device;
|
||||
if (device->deviceClassId() == mockDeviceClassId) {
|
||||
if (device->paramValue(mockDeviceAsyncParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorAsync;
|
||||
QTimer::singleShot(1000, device, [this, device, result, nodeId]() mutable {
|
||||
if (device->paramValue(mockDeviceBrokenParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorHardwareFailure;
|
||||
} else {
|
||||
result = generateBrowseItems(nodeId, result);
|
||||
}
|
||||
emit browseRequestFinished(result);
|
||||
});
|
||||
}
|
||||
else if (device->paramValue(mockDeviceBrokenParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorHardwareFailure;
|
||||
} else {
|
||||
result = generateBrowseItems(nodeId, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePluginMock::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
if (!myDevices().contains(device))
|
||||
|
|
@ -566,3 +590,38 @@ void DevicePluginMock::onPluginConfigChanged()
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePluginMock::generateBrowseItems(const QString &nodeId, Device::BrowseResult result)
|
||||
{
|
||||
result.status = Device::DeviceErrorNoError;
|
||||
|
||||
if (nodeId.isEmpty()) {
|
||||
result.items.append(BrowserItem("0", "Item 0", true));
|
||||
result.items.append(BrowserItem("1", "Item 1"));
|
||||
result.items.append(BrowserItem("2", "Item 2", true));
|
||||
result.items.append(BrowserItem("3", "Item 3"));
|
||||
result.items.append(BrowserItem("4", "Item 4"));
|
||||
}
|
||||
else if (nodeId == "0") {
|
||||
result.items.append(BrowserItem("5", "Item 5"));
|
||||
result.items.append(BrowserItem("6", "Item 6"));
|
||||
result.items.append(BrowserItem("7", "Item 7"));
|
||||
result.items.append(BrowserItem("8", "Item 8"));
|
||||
result.items.append(BrowserItem("9", "Item 9"));
|
||||
}
|
||||
else if (nodeId == "2") {
|
||||
result.items.append(BrowserItem("10", "Item 10", true));
|
||||
result.items.append(BrowserItem("11", "Item 11"));
|
||||
result.items.append(BrowserItem("12", "Item 12"));
|
||||
result.items.append(BrowserItem("13", "Item 13"));
|
||||
result.items.append(BrowserItem("14", "Item 14"));
|
||||
}
|
||||
else if (nodeId == "10") {
|
||||
result.items.append(BrowserItem("15", "Item 15"));
|
||||
result.items.append(BrowserItem("16", "Item 16"));
|
||||
} else {
|
||||
result.status = Device::DeviceErrorInvalidParameter;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ public:
|
|||
Device::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
||||
Device::DeviceError displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor) override;
|
||||
|
||||
Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId = QString()) override;
|
||||
|
||||
public slots:
|
||||
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
|
|
@ -72,6 +74,9 @@ private slots:
|
|||
void onChildDeviceDiscovered(const DeviceId &parentId);
|
||||
void onPluginConfigChanged();
|
||||
|
||||
private:
|
||||
Device::BrowseResult generateBrowseItems(const QString &nodeId, Device::BrowseResult result);
|
||||
|
||||
private:
|
||||
QHash<Device*, HttpDaemon*> m_daemons;
|
||||
QList<Device*> m_asyncSetupDevices;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
"displayName": "Mock Device",
|
||||
"interfaces": ["system", "light", "battery"],
|
||||
"createMethods": ["user", "discovery"],
|
||||
"browsable": true,
|
||||
"discoveryParamTypes": [
|
||||
{
|
||||
"id": "d222adb4-2f9c-4c3f-8655-76400d0fb6ce",
|
||||
|
|
|
|||
Loading…
Reference in New Issue