Add support for JS device plugins

This commit is contained in:
Michael Zanetti 2019-11-12 15:43:39 +01:00
parent 9322cc79e9
commit b97e4e5b0c
12 changed files with 361 additions and 33 deletions

View File

@ -269,6 +269,10 @@ DeviceDiscoveryInfo* DeviceManagerImplementation::discoverDevices(const DeviceCl
}
qCDebug(dcDeviceManager()) << "Discovery finished. Found devices:" << discoveryInfo->deviceDescriptors().count();
foreach (const DeviceDescriptor &descriptor, discoveryInfo->deviceDescriptors()) {
if (!descriptor.isValid()) {
qCWarning(dcDeviceManager()) << "Descriptor is invalid. Not adding to results";
continue;
}
m_discoveredDevices.insert(descriptor.id(), descriptor);
}
});
@ -296,8 +300,10 @@ DeviceSetupInfo* DeviceManagerImplementation::addConfiguredDevice(const DeviceCl
* Returns \l{DeviceError} to inform about the result. */
DeviceSetupInfo *DeviceManagerImplementation::addConfiguredDevice(const DeviceDescriptorId &deviceDescriptorId, const ParamList &params, const QString &name)
{
qWarning() << "Have descriptors" << m_discoveredDevices.keys();
DeviceDescriptor descriptor = m_discoveredDevices.value(deviceDescriptorId);
if (!descriptor.isValid()) {
qCWarning(dcDeviceManager()) << "Cannot add device. DeviceDescriptor" << deviceDescriptorId << "not found.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorDeviceDescriptorNotFound);
return info;
@ -305,11 +311,13 @@ DeviceSetupInfo *DeviceManagerImplementation::addConfiguredDevice(const DeviceDe
DeviceClass deviceClass = findDeviceClass(descriptor.deviceClassId());
if (!deviceClass.isValid()) {
qCWarning(dcDeviceManager()) << "Cannot add device. DeviceClass" << descriptor.deviceClassId() << "not found.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorDeviceClassNotFound);
return info;
}
if (!deviceClass.createMethods().testFlag(DeviceClass::CreateMethodDiscovery)) {
qCWarning(dcDeviceManager()) << "Cannot add device. This device cannot be added via discovery.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorCreationMethodNotSupported);
return info;
@ -675,12 +683,14 @@ DeviceSetupInfo* DeviceManagerImplementation::addConfiguredDeviceInternal(const
{
DeviceClass deviceClass = findDeviceClass(deviceClassId);
if (deviceClass.id().isNull()) {
qCWarning(dcDeviceManager()) << "Cannot add device. DeviceClass" << deviceClassId << "not found.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorDeviceClassNotFound);
return info;
}
if (deviceClass.setupMethod() != DeviceClass::SetupMethodJustAdd) {
qCWarning(dcDeviceManager()) << "Cannot add device. This device cannot be added this way. (SetupMethodJustAdd)";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorCreationMethodNotSupported);
return info;
@ -694,6 +704,7 @@ DeviceSetupInfo* DeviceManagerImplementation::addConfiguredDeviceInternal(const
DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId());
if (!plugin) {
qCWarning(dcDeviceManager()) << "Cannot add device. Plugin for device class" << deviceClass.name() << "not found.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(Device::DeviceErrorPluginNotFound);
return info;
@ -703,6 +714,7 @@ DeviceSetupInfo* DeviceManagerImplementation::addConfiguredDeviceInternal(const
ParamList effectiveParams = buildParams(deviceClass.paramTypes(), params);
Device::DeviceError paramsResult = DeviceUtils::verifyParams(deviceClass.paramTypes(), effectiveParams);
if (paramsResult != Device::DeviceErrorNoError) {
qCWarning(dcDeviceManager()) << "Cannot add device. Parameter verification failed.";
DeviceSetupInfo *info = new DeviceSetupInfo(nullptr, this);
info->finish(paramsResult);
return info;
@ -1107,8 +1119,20 @@ void DeviceManagerImplementation::loadPlugins()
}
ScriptDevicePlugin *plugin = new ScriptDevicePlugin(this);
plugin->loadScript("/home/micha/Develop/nymea-plugin-jstest/devicepluginjstest.js");
loadPlugin(plugin, plugin->metaData());
bool ret = plugin->loadScript("/home/micha/Develop/nymea-plugin-jstest/devicepluginjstest.js");
if (!ret) {
delete plugin;
qCWarning(dcDeviceManager()) << "JS plugin failed to load";
return;
}
PluginMetadata metaData(plugin->metaData());
if (!metaData.isValid()) {
qCWarning(dcDeviceManager()) << "Not loading JS plugin. Invalid metadata.";
foreach (const QString &error, metaData.validationErrors()) {
qCWarning(dcDeviceManager()) << error;
}
}
loadPlugin(plugin, metaData);
}
void DeviceManagerImplementation::loadPlugin(DevicePlugin *pluginIface, const PluginMetadata &metaData)

View File

@ -5,6 +5,7 @@
#include <QJsonDocument>
#include "loggingcategories.h"
#include <plugintimer.h>
ScriptDevicePlugin::ScriptDevicePlugin(QObject *parent) : DevicePlugin(parent)
{
@ -15,7 +16,7 @@ bool ScriptDevicePlugin::loadScript(const QString &fileName)
{
QFileInfo fi(fileName);
QString metaDataFileName = fileName + "on";
QString metaDataFileName = fi.absoluteDir().path() + '/' + fi.baseName() + ".json";
QFile metaDataFile(metaDataFileName);
if (!metaDataFile.open(QFile::ReadOnly)) {
@ -58,18 +59,18 @@ bool ScriptDevicePlugin::loadScript(const QString &fileName)
return false;
}
m_engine = new QJSEngine(this);
m_engine->installExtensions(QJSEngine::ConsoleExtension);
m_engine = new QQmlEngine(this);
m_engine->installExtensions(QJSEngine::AllExtensions);
m_engine->addImportPath(fi.absoluteDir().path() + "/node_modules/");
qCWarning(dcDeviceManager()) << "Engine import path list" << m_engine->importPathList();
QTextStream stream(&scriptFile);
QString contents = stream.readAll();
scriptFile.close();
QJSValue result = m_engine->evaluate(contents, fileName);
if (result.isError()) {
qCWarning(dcDeviceManager()) << "Error evaluating script" << fileName << result.toString();
m_pluginImport = m_engine->importModule(fileName);
if (m_pluginImport.isError()) {
qCWarning(dcDeviceManager()) << "Error loading plugin module" << m_pluginImport.errorType() << m_pluginImport.toString();
return false;
}
qCDebug(dcDeviceManager()) << "Loaded JS plugin" << fileName;
return true;
}
@ -80,5 +81,162 @@ QJsonObject ScriptDevicePlugin::metaData() const
void ScriptDevicePlugin::init()
{
qmlRegisterType<PluginTimerManager>();
qmlRegisterType<PluginTimer>();
QJSValue hardwareManagerObject = m_engine->newQObject(hardwareManager());
m_engine->globalObject().setProperty("hardwareManager", hardwareManagerObject);
if (!m_pluginImport.hasOwnProperty("init")) {
DevicePlugin::init();
return;
}
QJSValue initFunction = m_pluginImport.property("init");
QJSValue result = initFunction.call();
if (result.isError()) {
qCWarning(dcDeviceManager()) << "Error calling init in JS plugin:" << result.toString();
return;
}
}
void ScriptDevicePlugin::discoverDevices(DeviceDiscoveryInfo *info)
{
if (!m_pluginImport.hasOwnProperty("discoverDevices")) {
DevicePlugin::discoverDevices(info);
return;
}
ScriptDeviceDiscoveryInfo *scriptInfo = new ScriptDeviceDiscoveryInfo(info);
QJSValue jsInfo = m_engine->newQObject(scriptInfo);
QJSValue discoverFunction = m_pluginImport.property("discoverDevices");
QJSValue ret = discoverFunction.call({jsInfo});
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "discoverDevices script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::startPairing(DevicePairingInfo *info)
{
if (!m_pluginImport.hasOwnProperty("startPairing")) {
DevicePlugin::startPairing(info);
return;
}
ScriptDevicePairingInfo *scriptInfo = new ScriptDevicePairingInfo(info);
QJSValue jsInfo = m_engine->newQObject(scriptInfo);
QJSValue startPairingFunction = m_pluginImport.property("startPairing");
QJSValue ret = startPairingFunction.call({jsInfo});
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "startPairing script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret)
{
if (!m_pluginImport.hasOwnProperty("confirmPairing")) {
DevicePlugin::confirmPairing(info, username, secret);
return;
}
ScriptDevicePairingInfo *scriptInfo = new ScriptDevicePairingInfo(info);
QJSValue jsInfo = m_engine->newQObject(scriptInfo);
QJSValue confirmPairingFunction = m_pluginImport.property("confirmPairing");
QJSValue ret = confirmPairingFunction.call({jsInfo, username, secret});
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "confirmPairing script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::startMonitoringAutoDevices()
{
if (!m_pluginImport.hasOwnProperty("startMonitoringAutoDevices")) {
DevicePlugin::startMonitoringAutoDevices();
return;
}
QJSValue monitorFunction = m_pluginImport.property("startMonitoringAutoDevices");
QJSValue ret = monitorFunction.call();
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "startMonitoringAutoDevices failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::setupDevice(DeviceSetupInfo *info)
{
if (!m_pluginImport.hasOwnProperty("setupDevice")) {
DevicePlugin::setupDevice(info);
return;
}
QJSValue setupFunction = m_pluginImport.property("setupDevice");
Device *device = info->device();
ScriptDevice *scriptDevice = new ScriptDevice(device);
m_devices.insert(device, scriptDevice);
connect(device, &Device::destroyed, this, [this, device](){
m_devices.remove(device);
});
ScriptDeviceSetupInfo *scriptInfo = new ScriptDeviceSetupInfo(info, scriptDevice);
qWarning() << "Setup params" << info->device()->params();
QJSValue jsInfo = m_engine->newQObject(scriptInfo);
QJSValue ret = setupFunction.call({jsInfo});
if (ret.errorType() != QJSValue::NoError) {
qCWarning(dcDeviceManager()) << "setupDevice script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::postSetupDevice(Device *device)
{
if (!m_pluginImport.hasOwnProperty("postSetupDevice")) {
DevicePlugin::postSetupDevice(device);
return;
}
QJSValue postSetupFunction = m_pluginImport.property("postSetupDevice");
QJSValue jsDevice = m_engine->newQObject(m_devices.value(device));
QJSValue ret = postSetupFunction.call({jsDevice});
if (ret.errorType() != QJSValue::NoError) {
qCWarning(dcDeviceManager()) << "setupDevice script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::deviceRemoved(Device *device)
{
if (!m_pluginImport.hasOwnProperty("deviceRemoved")) {
DevicePlugin::deviceRemoved(device);
return;
}
QJSValue jsDevice = m_engine->newQObject(m_devices.value(device));
QJSValue deviceRemovedFunction = m_pluginImport.property("deviceRemoved");
QJSValue ret = deviceRemovedFunction.call({jsDevice});
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "deviceRemoved script failed to execute:\n" << ret.toString();
}
}
void ScriptDevicePlugin::executeAction(DeviceActionInfo *info)
{
if (!m_pluginImport.hasOwnProperty("executeAction")) {
DevicePlugin::executeAction(info);
return;
}
ScriptDevice *scriptDevice = m_devices.value(info->device());
QJSValue jsDevice = m_engine->newQObject(scriptDevice);
ScriptDeviceActionInfo *scriptInfo = new ScriptDeviceActionInfo(info, scriptDevice);
QJSValue jsInfo = m_engine->newQObject(scriptInfo);
QJSValue executeActionFunction = m_pluginImport.property("executeAction");
QJSValue ret = executeActionFunction.call({jsInfo});
if (ret.isError()) {
qCWarning(dcDeviceManager()) << "executeAction script failed to execute:\n" << ret.toString();
}
}

View File

@ -3,9 +3,137 @@
#include "devices/deviceplugin.h"
#include <QJSEngine>
#include <QQmlEngine>
#include <QJsonObject>
class ScriptDeviceDiscoveryInfo: public QObject
{
Q_OBJECT
public:
ScriptDeviceDiscoveryInfo(DeviceDiscoveryInfo *info): QObject(info), m_info(info) {
connect(info, &DeviceDiscoveryInfo::aborted, this, &ScriptDeviceDiscoveryInfo::aborted);
connect(info, &DeviceDiscoveryInfo::finished, this, &ScriptDeviceDiscoveryInfo::finished);
}
Q_INVOKABLE void addDeviceDescriptor(const QUuid &deviceClassId, const QString &title, const QString &description = QString(), const QVariantList &params = QVariantList(), const QUuid &parentDeviceId = QUuid()) {
ParamList paramList;
for (int i = 0; i < params.count(); i++) {
paramList << Param(params.at(i).toMap().value("paramTypeId").toUuid(), params.at(i).toMap().value("value"));
}
DeviceDescriptor d(deviceClassId, title, description, parentDeviceId);
d.setParams(paramList);
m_info->addDeviceDescriptor(d);
}
Q_INVOKABLE void finish(Device::DeviceError status = Device::DeviceErrorNoError, const QString &displayMessage = QString()) {
m_info->finish(status, displayMessage);
}
signals:
void aborted();
void finished();
private:
DeviceDiscoveryInfo *m_info = nullptr;
};
class ScriptDevice: public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
ScriptDevice(Device *device): QObject(device), m_device(device) {
connect(device, &Device::nameChanged, this, &ScriptDevice::nameChanged);
}
QString name() const { return m_device->name(); }
void setName(const QString &name) { m_device->setName(name); }
Q_INVOKABLE QVariant paramValue(const QUuid &paramTypeId) { return m_device->paramValue(paramTypeId); }
Q_INVOKABLE void setParamValue(const QUuid &paramTypeId, const QVariant &value) { m_device->setParamValue(paramTypeId, value); }
Q_INVOKABLE QVariant stateValue(const QUuid &stateTypeId) { return m_device->stateValue(stateTypeId); }
Q_INVOKABLE void setStateValue(const QUuid &stateTypeId, const QVariant &value) { m_device->setStateValue(stateTypeId, value); }
signals:
void nameChanged();
private:
Device *m_device = nullptr;
};
class ScriptDeviceSetupInfo: public QObject
{
Q_OBJECT
Q_PROPERTY(ScriptDevice* device READ device CONSTANT)
public:
ScriptDeviceSetupInfo(DeviceSetupInfo *info, ScriptDevice *scriptDevice): QObject(info), m_info(info), m_device(scriptDevice) {
connect(info, &DeviceSetupInfo::aborted, this, &ScriptDeviceSetupInfo::aborted);
connect(info, &DeviceSetupInfo::finished, this, &ScriptDeviceSetupInfo::finished);
}
Q_INVOKABLE void finish(Device::DeviceError status = Device::DeviceErrorNoError, const QString &displayMessage = QString()) {
m_info->finish(status, displayMessage);
}
ScriptDevice* device() const { return m_device; }
signals:
void aborted();
void finished();
private:
DeviceSetupInfo *m_info = nullptr;
ScriptDevice* m_device = nullptr;
};
class ScriptDevicePairingInfo: public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid deviceClassId READ deviceClassId CONSTANT)
Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT)
Q_PROPERTY(QString deviceName READ deviceName CONSTANT)
Q_PROPERTY(QUuid parentDeviceId READ parentDeviceId CONSTANT)
Q_PROPERTY(QUrl oAuthUrl READ oAuthUrl WRITE setOAuthUrl)
public:
ScriptDevicePairingInfo(DevicePairingInfo* info): QObject(info), m_info(info) {
connect(info, &DevicePairingInfo::aborted, this, &ScriptDevicePairingInfo::aborted);
connect(info, &DevicePairingInfo::finished, this, &ScriptDevicePairingInfo::finished);
}
Q_INVOKABLE QVariant paramValue(const QUuid &paramTypeId) { return m_info->params().paramValue(paramTypeId); }
Q_INVOKABLE void finish(Device::DeviceError status = Device::DeviceErrorNoError, const QString &displayMessage = QString()) {
m_info->finish(status, displayMessage);
}
QUuid deviceClassId() const { return m_info->deviceClassId(); }
QUuid deviceId() const { return m_info->deviceId(); }
QString deviceName() const { return m_info->deviceName(); }
QUuid parentDeviceId() const { return m_info->parentDeviceId(); }
QUrl oAuthUrl() const { return m_info->oAuthUrl(); }
void setOAuthUrl(const QUrl &oAuthUrl) { m_info->setOAuthUrl(oAuthUrl); }
signals:
void aborted();
void finished();
private:
DevicePairingInfo *m_info = nullptr;
};
class ScriptDeviceActionInfo: public QObject
{
Q_OBJECT
Q_PROPERTY(ScriptDevice* device READ device CONSTANT)
Q_PROPERTY(QUuid actionTypeId READ actionTypeId CONSTANT)
public:
ScriptDeviceActionInfo(DeviceActionInfo* info, ScriptDevice* scriptDevice): QObject(info), m_info(info), m_device(scriptDevice) {
connect(info, &DeviceActionInfo::finished, this, &ScriptDeviceActionInfo::finished);
connect(info, &DeviceActionInfo::aborted, this, &ScriptDeviceActionInfo::aborted);
}
ScriptDevice* device() const { return m_device; }
QUuid actionTypeId() const { return m_info->action().actionTypeId(); }
Q_INVOKABLE QVariant paramValue(const QUuid &paramTypeId) { return m_info->action().params().paramValue(paramTypeId); }
Q_INVOKABLE void finish(Device::DeviceError status = Device::DeviceErrorNoError, const QString &displayMessage = QString()) {
m_info->finish(status, displayMessage);
}
signals:
void aborted();
void finished();
private:
DeviceActionInfo* m_info = nullptr;
ScriptDevice* m_device = nullptr;
};
class ScriptDevicePlugin : public DevicePlugin
{
Q_OBJECT
@ -16,13 +144,21 @@ public:
QJsonObject metaData() const;
void init() override;
signals:
public slots:
void startMonitoringAutoDevices() override;
void discoverDevices(DeviceDiscoveryInfo *info) override;
void startPairing(DevicePairingInfo *info) override;
void confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) override;
void setupDevice(DeviceSetupInfo *info) override;
void postSetupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void executeAction(DeviceActionInfo *info) override;
void browseDevice(BrowseResult *result) override;
private:
QJSEngine *m_engine = nullptr;
QQmlEngine *m_engine = nullptr;
QJsonObject m_metaData;
QJSValue m_pluginImport;
QHash<Device*, ScriptDevice*> m_devices;
};
#endif // SCRIPTDEVICEPLUGIN_H

View File

@ -455,6 +455,8 @@ JsonReply *DeviceHandler::GetDiscoveredDevices(const QVariantMap &params) const
QVariantList deviceDescriptorList;
foreach (const DeviceDescriptor &deviceDescriptor, info->deviceDescriptors()) {
deviceDescriptorList.append(pack(deviceDescriptor));
qWarning() << "*** Discovery result:" << deviceDescriptor.params();
qWarning() << "Packed:" << pack(deviceDescriptor);
}
returns.insert("deviceDescriptors", deviceDescriptorList);
}

View File

@ -32,6 +32,7 @@ class DeviceManager;
class LIBNYMEA_EXPORT DeviceSetupInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(Device* device READ device CONSTANT)
public:
explicit DeviceSetupInfo(Device *device, DeviceManager *deviceManager, quint32 timeout = 0);

View File

@ -185,7 +185,7 @@ Interface DeviceUtils::loadInterface(const QString &name)
ActionTypes actionTypes;
EventTypes eventTypes;
foreach (const QVariant &stateVariant, content.value("states").toList()) {
StateType stateType(StateTypeId::fromUuid(QUuid()));
StateType stateType;
stateType.setName(stateVariant.toMap().value("name").toString());
stateType.setType(QVariant::nameToType(stateVariant.toMap().value("type").toByteArray()));
stateType.setPossibleValues(stateVariant.toMap().value("allowedValues").toList());
@ -193,7 +193,7 @@ Interface DeviceUtils::loadInterface(const QString &name)
stateType.setMaxValue(stateVariant.toMap().value("maxValue"));
stateTypes.append(stateType);
EventType stateChangeEventType(EventTypeId::fromUuid(QUuid()));
EventType stateChangeEventType;
stateChangeEventType.setName(stateType.name());
ParamType stateChangeEventParamType;
stateChangeEventParamType.setName(stateType.name());
@ -205,7 +205,7 @@ Interface DeviceUtils::loadInterface(const QString &name)
eventTypes.append(stateChangeEventType);
if (stateVariant.toMap().value("writable", false).toBool()) {
ActionType stateChangeActionType(ActionTypeId::fromUuid(QUuid()));
ActionType stateChangeActionType;
stateChangeActionType.setName(stateType.name());
stateChangeActionType.setParamTypes(ParamTypes() << stateChangeEventParamType);
actionTypes.append(stateChangeActionType);
@ -213,7 +213,7 @@ Interface DeviceUtils::loadInterface(const QString &name)
}
foreach (const QVariant &actionVariant, content.value("actions").toList()) {
ActionType actionType(ActionTypeId::fromUuid(QUuid()));
ActionType actionType;
actionType.setName(actionVariant.toMap().value("name").toString());
ParamTypes paramTypes;
foreach (const QVariant &actionParamVariant, actionVariant.toMap().value("params").toList()) {
@ -229,7 +229,7 @@ Interface DeviceUtils::loadInterface(const QString &name)
}
foreach (const QVariant &eventVariant, content.value("events").toList()) {
EventType eventType(EventTypeId::fromUuid(QUuid()));
EventType eventType;
eventType.setName(eventVariant.toMap().value("name").toString());
ParamTypes paramTypes;
foreach (const QVariant &eventParamVariant, eventVariant.toMap().value("params").toList()) {

View File

@ -69,7 +69,6 @@
HardwareManager::HardwareManager(QObject *parent) :
QObject(parent)
{
}
/*! Sets the given \a resource to \a enabled. This allows to enable/disable individual \l{HardwareResource}{HardwareResources}. */

View File

@ -38,6 +38,7 @@ class HardwareResource;
class HardwareManager : public QObject
{
Q_OBJECT
Q_PROPERTY(PluginTimerManager* pluginTimerManager READ pluginTimerManager CONSTANT)
public:
HardwareManager(QObject *parent = nullptr);

View File

@ -66,8 +66,8 @@ public:
PluginTimerManager(QObject *parent = nullptr);
virtual ~PluginTimerManager() = default;
virtual PluginTimer *registerTimer(int seconds = 60) = 0;
virtual void unregisterTimer(PluginTimer *timer = nullptr) = 0;
Q_INVOKABLE virtual PluginTimer *registerTimer(int seconds = 60) = 0;
Q_INVOKABLE virtual void unregisterTimer(PluginTimer *timer = nullptr) = 0;
};
#endif // PLUGINTIMER_H

View File

@ -29,13 +29,20 @@
#include "libnymea.h"
#define DECLARE_TYPE_ID(type) class type##Id: public QUuid \
class GadgetUuid: public QUuid
{
Q_GADGET
public:
GadgetUuid() {}
GadgetUuid(const QUuid &uuid): QUuid(uuid) {}
};
#define DECLARE_TYPE_ID(type) class type##Id: public GadgetUuid \
{ \
public: \
type##Id(const QUuid &uuid): QUuid(uuid) {} \
type##Id(): QUuid() {} \
static type##Id create##type##Id() { return type##Id(QUuid::createUuid().toString()); } \
static type##Id fromUuid(const QUuid &uuid) { return type##Id(uuid.toString()); } \
type##Id(const QUuid &uuid): GadgetUuid(uuid) {} \
type##Id(): GadgetUuid() {} \
static type##Id create##type##Id() { return type##Id(QUuid::createUuid()); } \
bool operator==(const type##Id &other) const { \
return toString() == other.toString(); \
} \

View File

@ -599,7 +599,7 @@ void TestLogging::testHouseKeeping()
deviceParams.append(httpParam);
params.insert("deviceParams", deviceParams);
QVariant response = injectAndWait("Devices.AddConfiguredDevice", params);
DeviceId deviceId = DeviceId::fromUuid(response.toMap().value("params").toMap().value("deviceId").toUuid());
DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toUuid());
QVERIFY2(!deviceId.isNull(), "Something went wrong creating the device for testing.");
// Trigger something that creates a logging entry

View File

@ -2766,7 +2766,7 @@ void TestRules::testInitStatesActive()
params.insert("exitActions", exitActions);
QVariant response = injectAndWait("Rules.AddRule", params);
RuleId ruleId = RuleId::fromUuid(response.toMap().value("params").toMap().value("ruleId").toUuid());
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toUuid());
QVERIFY2(!ruleId.isNull(), "Error adding rule");
// Get the current state value, make sure it's false
@ -3140,7 +3140,7 @@ void TestRules::testHousekeeping()
deviceParams.append(httpParam);
params.insert("deviceParams", deviceParams);
QVariant response = injectAndWait("Devices.AddConfiguredDevice", params);
DeviceId deviceId = DeviceId::fromUuid(response.toMap().value("params").toMap().value("deviceId").toUuid());
DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toUuid());
QVERIFY2(!deviceId.isNull(), "Something went wrong creating the device for testing.");
// Create a rule with this device
@ -3181,7 +3181,7 @@ void TestRules::testHousekeeping()
}
response = injectAndWait("Rules.AddRule", params);
RuleId ruleId = RuleId::fromUuid(response.toMap().value("params").toMap().value("ruleId").toUuid());
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toUuid());
// Verfy that the rule has been created successfully and our device is in there.