Initial attempt to script a plugin

This commit is contained in:
Michael Zanetti 2019-11-07 11:32:58 +01:00
parent 6cdcd47f9b
commit 9322cc79e9
4 changed files with 120 additions and 1 deletions

View File

@ -23,6 +23,7 @@
#include "devicemanagerimplementation.h"
#include "translator.h"
#include "scriptdeviceplugin.h"
#include "loggingcategories.h"
#include "typeutils.h"
@ -1104,6 +1105,10 @@ void DeviceManagerImplementation::loadPlugins()
loadPlugin(pluginIface, metaData);
}
}
ScriptDevicePlugin *plugin = new ScriptDevicePlugin(this);
plugin->loadScript("/home/micha/Develop/nymea-plugin-jstest/devicepluginjstest.js");
loadPlugin(plugin, plugin->metaData());
}
void DeviceManagerImplementation::loadPlugin(DevicePlugin *pluginIface, const PluginMetadata &metaData)

View File

@ -0,0 +1,84 @@
#include "scriptdeviceplugin.h"
#include <QQmlEngine>
#include <QDir>
#include <QJsonDocument>
#include "loggingcategories.h"
ScriptDevicePlugin::ScriptDevicePlugin(QObject *parent) : DevicePlugin(parent)
{
}
bool ScriptDevicePlugin::loadScript(const QString &fileName)
{
QFileInfo fi(fileName);
QString metaDataFileName = fileName + "on";
QFile metaDataFile(metaDataFileName);
if (!metaDataFile.open(QFile::ReadOnly)) {
qCWarning(dcDeviceManager()) << "Failed to open plugin metadata at" << metaDataFileName;
return false;
}
QJsonParseError error;
QByteArray data = metaDataFile.readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
metaDataFile.close();
if (error.error != QJsonParseError::NoError) {
int errorOffset = error.offset;
int newLineIndex = data.indexOf("\n");
int lineIndex = 1;
while (newLineIndex > 0 && errorOffset > newLineIndex) {
data.remove(0, newLineIndex + 2);
errorOffset -= (newLineIndex + 2);
newLineIndex = data.indexOf("\n");
lineIndex++;
}
if (newLineIndex >= 0) {
data = data.left(newLineIndex);
}
QString spacer;
for (int i = 0; i < errorOffset; i++) {
spacer += ' ';
}
QDebug dbg = qWarning(dcDeviceManager()).nospace().noquote();
dbg << metaDataFileName << ":" << lineIndex << ":" << errorOffset + 2 << ": error: JSON parsing failed: " << error.errorString() << ": " << data.trimmed() << endl;
dbg << data << endl;
dbg << spacer << "^";
return false;
}
m_metaData = QJsonObject::fromVariantMap(jsonDoc.toVariant().toMap());
QFile scriptFile(fileName);
if (!scriptFile.open(QIODevice::ReadOnly)) {
return false;
}
m_engine = new QJSEngine(this);
m_engine->installExtensions(QJSEngine::ConsoleExtension);
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();
return false;
}
return true;
}
QJsonObject ScriptDevicePlugin::metaData() const
{
return m_metaData;
}
void ScriptDevicePlugin::init()
{
}

View File

@ -0,0 +1,28 @@
#ifndef SCRIPTDEVICEPLUGIN_H
#define SCRIPTDEVICEPLUGIN_H
#include "devices/deviceplugin.h"
#include <QJSEngine>
#include <QJsonObject>
class ScriptDevicePlugin : public DevicePlugin
{
Q_OBJECT
public:
explicit ScriptDevicePlugin(QObject *parent = nullptr);
bool loadScript(const QString &fileName);
QJsonObject metaData() const;
void init() override;
signals:
public slots:
private:
QJSEngine *m_engine = nullptr;
QJsonObject m_metaData;
};
#endif // SCRIPTDEVICEPLUGIN_H

View File

@ -3,7 +3,7 @@ TARGET = nymea-core
include(../nymea.pri)
QT += sql
QT += sql qml
INCLUDEPATH += $$top_srcdir/libnymea
LIBS += -L$$top_builddir/libnymea/ -lnymea -lssl -lcrypto -lnymea-mqtt
@ -17,6 +17,7 @@ RESOURCES += $$top_srcdir/icons.qrc \
HEADERS += nymeacore.h \
devices/devicemanagerimplementation.h \
devices/scriptdeviceplugin.h \
devices/translator.h \
experiences/experiencemanager.h \
jsonrpc/jsonrpcserverimplementation.h \
@ -91,6 +92,7 @@ HEADERS += nymeacore.h \
SOURCES += nymeacore.cpp \
devices/devicemanagerimplementation.cpp \
devices/scriptdeviceplugin.cpp \
devices/translator.cpp \
experiences/experiencemanager.cpp \
jsonrpc/jsonrpcserverimplementation.cpp \