Add support for JS device plugins
This commit is contained in:
parent
9322cc79e9
commit
b97e4e5b0c
@ -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 ¶ms, 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)
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 ¶ms = 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 ¶mTypeId) { return m_device->paramValue(paramTypeId); }
|
||||
Q_INVOKABLE void setParamValue(const QUuid ¶mTypeId, 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 ¶mTypeId) { 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 ¶mTypeId) { 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
|
||||
|
||||
@ -455,6 +455,8 @@ JsonReply *DeviceHandler::GetDiscoveredDevices(const QVariantMap ¶ms) 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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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}. */
|
||||
|
||||
@ -38,6 +38,7 @@ class HardwareResource;
|
||||
class HardwareManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(PluginTimerManager* pluginTimerManager READ pluginTimerManager CONSTANT)
|
||||
|
||||
public:
|
||||
HardwareManager(QObject *parent = nullptr);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(); \
|
||||
} \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user