diff --git a/libnymea-core/devices/devicemanagerimplementation.cpp b/libnymea-core/devices/devicemanagerimplementation.cpp index 48c365e5..39bbae23 100644 --- a/libnymea-core/devices/devicemanagerimplementation.cpp +++ b/libnymea-core/devices/devicemanagerimplementation.cpp @@ -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) diff --git a/libnymea-core/devices/scriptdeviceplugin.cpp b/libnymea-core/devices/scriptdeviceplugin.cpp new file mode 100644 index 00000000..89fa90c2 --- /dev/null +++ b/libnymea-core/devices/scriptdeviceplugin.cpp @@ -0,0 +1,84 @@ +#include "scriptdeviceplugin.h" + +#include +#include +#include + +#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() +{ + +} diff --git a/libnymea-core/devices/scriptdeviceplugin.h b/libnymea-core/devices/scriptdeviceplugin.h new file mode 100644 index 00000000..c28c07a5 --- /dev/null +++ b/libnymea-core/devices/scriptdeviceplugin.h @@ -0,0 +1,28 @@ +#ifndef SCRIPTDEVICEPLUGIN_H +#define SCRIPTDEVICEPLUGIN_H + +#include "devices/deviceplugin.h" + +#include +#include + +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 diff --git a/libnymea-core/libnymea-core.pro b/libnymea-core/libnymea-core.pro index 5e5fbf32..5d4ceceb 100644 --- a/libnymea-core/libnymea-core.pro +++ b/libnymea-core/libnymea-core.pro @@ -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 \