Add Thing and Things types to script engine
This commit is contained in:
parent
84163288b0
commit
22e75b08df
@ -1235,12 +1235,7 @@ Vendor ThingManagerImplementation::translateVendor(const Vendor &vendor, const Q
|
||||
|
||||
Thing *ThingManagerImplementation::findConfiguredThing(const ThingId &id) const
|
||||
{
|
||||
foreach (Thing *thing, m_configuredThings) {
|
||||
if (thing->id() == id) {
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return m_configuredThings.value(id);
|
||||
}
|
||||
|
||||
Things ThingManagerImplementation::configuredThings() const
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
|
||||
namespace nymeaserver {
|
||||
|
||||
using namespace scriptengine;
|
||||
|
||||
ScriptsHandler::ScriptsHandler(ScriptEngine *scriptEngine, QObject *parent):
|
||||
JsonHandler(parent),
|
||||
m_engine(scriptEngine)
|
||||
@ -43,7 +45,7 @@ ScriptsHandler::ScriptsHandler(ScriptEngine *scriptEngine, QObject *parent):
|
||||
registerEnum<ScriptEngine::ScriptError>();
|
||||
registerEnum<ScriptEngine::ScriptMessageType>();
|
||||
|
||||
registerObject<Script, Scripts>();
|
||||
registerObject<scriptengine::Script, Scripts>();
|
||||
|
||||
QVariantMap params, returns;
|
||||
QString description;
|
||||
|
||||
@ -42,7 +42,7 @@ class ScriptsHandler : public JsonHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptsHandler(ScriptEngine *scriptEngine, QObject *parent = nullptr);
|
||||
explicit ScriptsHandler(scriptengine::ScriptEngine *scriptEngine, QObject *parent = nullptr);
|
||||
|
||||
QString name() const override;
|
||||
|
||||
@ -61,7 +61,7 @@ signals:
|
||||
void ScriptLogMessage(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
ScriptEngine *m_engine = nullptr;
|
||||
scriptengine::ScriptEngine *m_engine = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -61,6 +61,8 @@ HEADERS += nymeacore.h \
|
||||
hardware/network/macaddressdatabasereplyimpl.h \
|
||||
hardware/serialport/serialportmonitor.h \
|
||||
hardware/zwave/zwavehardwareresourceimplementation.h \
|
||||
scriptengine/scriptthing.h \
|
||||
scriptengine/scriptthings.h \
|
||||
zwave/zwavedevicedatabase.h \
|
||||
zwave/zwavemanagerreply.h \
|
||||
zwave/zwavenodeimplementation.h \
|
||||
@ -174,6 +176,8 @@ SOURCES += nymeacore.cpp \
|
||||
hardware/network/macaddressdatabasereplyimpl.cpp \
|
||||
hardware/serialport/serialportmonitor.cpp \
|
||||
hardware/zwave/zwavehardwareresourceimplementation.cpp \
|
||||
scriptengine/scriptthing.cpp \
|
||||
scriptengine/scriptthings.cpp \
|
||||
zwave/zwavedevicedatabase.cpp \
|
||||
zwave/zwavemanagerreply.cpp \
|
||||
zwave/zwavenodeimplementation.cpp \
|
||||
|
||||
@ -135,7 +135,7 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
|
||||
m_logger->setThingManager(m_thingManager);
|
||||
|
||||
qCDebug(dcCore()) << "Creating Script Engine";
|
||||
m_scriptEngine = new ScriptEngine(m_thingManager, this);
|
||||
m_scriptEngine = new scriptengine::ScriptEngine(m_thingManager, this);
|
||||
m_serverManager->jsonServer()->registerHandler(new ScriptsHandler(m_scriptEngine, m_scriptEngine));
|
||||
|
||||
qCDebug(dcCore()) << "Creating Tags Storage";
|
||||
|
||||
@ -64,13 +64,17 @@ class UserManager;
|
||||
class Platform;
|
||||
class System;
|
||||
class ExperienceManager;
|
||||
class ScriptEngine;
|
||||
class CloudManager;
|
||||
class ZigbeeManager;
|
||||
class ZWaveManager;
|
||||
class ModbusRtuManager;
|
||||
class SerialPortMonitor;
|
||||
|
||||
namespace scriptengine {
|
||||
class ScriptEngine;
|
||||
}
|
||||
using namespace scriptengine;
|
||||
|
||||
class NymeaCore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -30,7 +30,11 @@
|
||||
|
||||
#include "script.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
Script::Script()
|
||||
{
|
||||
@ -79,3 +83,4 @@ void Scripts::put(const QVariant &value)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include <QObject>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class Script
|
||||
{
|
||||
@ -75,9 +76,9 @@ public:
|
||||
Q_INVOKABLE QVariant get(int index);
|
||||
Q_INVOKABLE void put(const QVariant &value);
|
||||
};
|
||||
|
||||
}
|
||||
Q_DECLARE_METATYPE(nymeaserver::Script)
|
||||
Q_DECLARE_METATYPE(nymeaserver::Scripts)
|
||||
}
|
||||
Q_DECLARE_METATYPE(nymeaserver::scriptengine::Script)
|
||||
Q_DECLARE_METATYPE(nymeaserver::scriptengine::Scripts)
|
||||
|
||||
#endif // SCRIPT_H
|
||||
|
||||
@ -36,9 +36,11 @@
|
||||
#include <QQmlEngine>
|
||||
#include <qqml.h>
|
||||
|
||||
#include "loggingcategories.h"
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptAction::ScriptAction(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -159,3 +161,4 @@ void ScriptAction::execute(const QVariantMap ¶ms)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
class ThingManager;
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptAction : public QObject, public QQmlParserStatus
|
||||
{
|
||||
@ -82,6 +83,7 @@ public:
|
||||
QString m_actionName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTACTION_H
|
||||
|
||||
@ -29,9 +29,13 @@
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "scriptalarm.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptAlarm::ScriptAlarm(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -151,3 +155,6 @@ void ScriptAlarm::updateActive()
|
||||
emit activeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptAlarm : public QObject
|
||||
{
|
||||
@ -97,4 +99,7 @@ private:
|
||||
int m_timerId = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTALARM_H
|
||||
|
||||
@ -38,6 +38,8 @@
|
||||
#include "scriptinterfaceaction.h"
|
||||
#include "scriptinterfacestate.h"
|
||||
#include "scriptinterfaceevent.h"
|
||||
#include "scriptthing.h"
|
||||
#include "scriptthings.h"
|
||||
|
||||
#include "nymeasettings.h"
|
||||
|
||||
@ -51,7 +53,10 @@
|
||||
|
||||
#include <QDir>
|
||||
|
||||
NYMEA_LOGGING_CATEGORY(dcScriptEngine, "ScriptEngine")
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
QList<ScriptEngine*> ScriptEngine::s_engines;
|
||||
QtMessageHandler ScriptEngine::s_upstreamMessageHandler;
|
||||
@ -68,6 +73,8 @@ ScriptEngine::ScriptEngine(ThingManager *thingManager, QObject *parent) : QObjec
|
||||
qmlRegisterType<ScriptInterfaceState>("nymea", 1, 0, "InterfaceState");
|
||||
qmlRegisterType<ScriptInterfaceEvent>("nymea", 1, 0, "InterfaceEvent");
|
||||
qmlRegisterType<ScriptAlarm>("nymea", 1, 0, "Alarm");
|
||||
qmlRegisterType<ScriptThing>("nymea", 1, 0, "Thing");
|
||||
qmlRegisterType<ScriptThings>("nymea", 1, 0, "Things");
|
||||
|
||||
m_engine = new QQmlEngine(this);
|
||||
m_engine->setProperty("thingManager", reinterpret_cast<quint64>(m_thingManager));
|
||||
@ -486,3 +493,4 @@ void ScriptEngine::logCategoryFilter(QLoggingCategory *category)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "script.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptEngine : public QObject
|
||||
{
|
||||
@ -115,6 +116,7 @@ private:
|
||||
static QMutex s_loggerMutex;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTENGINE_H
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptEvent::ScriptEvent(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -117,4 +118,4 @@ void ScriptEvent::onEventTriggered(const Event &event)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptParams;
|
||||
|
||||
@ -82,6 +83,7 @@ private:
|
||||
QString m_eventName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTEVENT_H
|
||||
|
||||
@ -36,9 +36,11 @@
|
||||
#include <QQmlEngine>
|
||||
#include <qqml.h>
|
||||
|
||||
#include "loggingcategories.h"
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptInterfaceAction::ScriptInterfaceAction(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -124,3 +126,4 @@ void ScriptInterfaceAction::execute(const QVariantMap ¶ms)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
class ThingManager;
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptInterfaceAction : public QObject, public QQmlParserStatus
|
||||
{
|
||||
@ -68,6 +69,7 @@ public:
|
||||
QString m_actionName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTINTERFACEACTION_H
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptInterfaceEvent::ScriptInterfaceEvent(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -100,4 +101,4 @@ void ScriptInterfaceEvent::onEventTriggered(const Event &event)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptParams;
|
||||
|
||||
@ -75,6 +76,7 @@ private:
|
||||
QString m_eventName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTINTERFACEEVENT_H
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptInterfaceState::ScriptInterfaceState(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -91,4 +92,4 @@ void ScriptInterfaceState::onStateChanged(Thing *thing, const StateTypeId &state
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptParams;
|
||||
|
||||
@ -75,6 +76,7 @@ private:
|
||||
QString m_stateName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTINTERFACESTATE_H
|
||||
|
||||
@ -30,13 +30,15 @@
|
||||
|
||||
#include "scriptstate.h"
|
||||
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <qqml.h>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptState::ScriptState(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@ -238,6 +240,9 @@ void ScriptState::onThingStateChanged(Thing *thing, const StateTypeId &stateType
|
||||
|
||||
void ScriptState::connectToThing()
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection);
|
||||
}
|
||||
Thing *thing = m_thingManager->findConfiguredThing(ThingId(m_thingId));
|
||||
if (!thing) {
|
||||
qCDebug(dcScriptEngine()) << "Can't find thing with id" << m_thingId << "(yet)";
|
||||
@ -252,7 +257,7 @@ void ScriptState::connectToThing()
|
||||
qCDebug(dcScriptEngine()) << "Thing setup for" << thing->name() << "not complete yet";
|
||||
}
|
||||
|
||||
connect(thing, &Thing::setupStatusChanged, this, [this, thing](){
|
||||
m_connection = connect(thing, &Thing::setupStatusChanged, this, [this, thing](){
|
||||
if (thing->setupStatus() == Thing::ThingSetupStatusComplete) {
|
||||
qCDebug(dcScriptEngine()) << "Thing setup for" << thing->name() << "completed";
|
||||
if (!m_valueCache.isNull()) {
|
||||
@ -263,3 +268,4 @@ void ScriptState::connectToThing()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "integrations/thingactioninfo.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptState : public QObject, public QQmlParserStatus
|
||||
{
|
||||
@ -98,8 +99,11 @@ private:
|
||||
QVariant m_valueCache;
|
||||
|
||||
QVariant m_valueStore;
|
||||
|
||||
QMetaObject::Connection m_connection;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTSTATE_H
|
||||
|
||||
195
libnymea-core/scriptengine/scriptthing.cpp
Normal file
195
libnymea-core/scriptengine/scriptthing.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "scriptthing.h"
|
||||
|
||||
#include <qqml.h>
|
||||
#include <QQmlEngine>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptThing::ScriptThing(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ScriptThing::ScriptThing(ThingManager *thingManager, QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
init(thingManager);
|
||||
}
|
||||
|
||||
void ScriptThing::classBegin()
|
||||
{
|
||||
init(reinterpret_cast<ThingManager*>(qmlEngine(this)->property("thingManager").toULongLong()));
|
||||
}
|
||||
|
||||
void ScriptThing::componentComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString ScriptThing::thingId() const
|
||||
{
|
||||
return m_thingId.toString();
|
||||
}
|
||||
|
||||
void ScriptThing::setThingId(const QString &thingId)
|
||||
{
|
||||
if (m_thingId != ThingId(thingId)) {
|
||||
m_thingId = ThingId(thingId);
|
||||
emit thingIdChanged();
|
||||
emit nameChanged();
|
||||
connectToThing();
|
||||
}
|
||||
}
|
||||
|
||||
QString ScriptThing::name() const
|
||||
{
|
||||
Thing *thing = m_thingManager->findConfiguredThing(m_thingId);
|
||||
if (!thing) {
|
||||
return QString();
|
||||
}
|
||||
return thing->name();
|
||||
}
|
||||
|
||||
QVariant ScriptThing::stateValue(const QString &stateName) const
|
||||
{
|
||||
Thing *thing = m_thingManager->findConfiguredThing(m_thingId);
|
||||
if (!thing) {
|
||||
return QVariant();
|
||||
}
|
||||
return thing->stateValue(stateName);
|
||||
}
|
||||
|
||||
void ScriptThing::setStateValue(const QString &stateName, const QVariant &value)
|
||||
{
|
||||
executeAction(stateName, {{stateName, value}});
|
||||
}
|
||||
|
||||
void ScriptThing::executeAction(const QString &actionName, const QVariantMap ¶ms)
|
||||
{
|
||||
Thing *thing = m_thingManager->findConfiguredThing(m_thingId);
|
||||
if (!thing) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActionType actionType = thing->thingClass().actionTypes().findByName(actionName);
|
||||
if (actionType.id().isNull()) { // Try to find by id for now, for compatiblity sake
|
||||
actionType = thing->thingClass().actionTypes().findById(QUuid(actionName));
|
||||
}
|
||||
if (actionType.id().isNull()) {
|
||||
qCWarning(dcScriptEngine()) << "Thing" << thing->name() << "does not have action" << actionName;
|
||||
return;
|
||||
}
|
||||
|
||||
Action action(actionType.id(), thing->id(), Action::TriggeredByScript);
|
||||
ParamList paramList;
|
||||
foreach (const QString ¶mNameOrId, params.keys()) {
|
||||
ParamType paramType;
|
||||
if (!ParamTypeId(paramNameOrId).isNull()) {
|
||||
paramType = actionType.paramTypes().findById(ParamTypeId(paramNameOrId));
|
||||
} else {
|
||||
paramType = actionType.paramTypes().findByName(paramNameOrId);
|
||||
}
|
||||
if (paramType.id().isNull()) {
|
||||
qCWarning(dcScriptEngine()) << "Invalid param id or name";
|
||||
continue;
|
||||
}
|
||||
paramList << Param(paramType.id(), params.value(paramNameOrId));
|
||||
}
|
||||
action.setParams(paramList);
|
||||
qCDebug(dcScriptEngine()) << "Executing action:" << action.thingId().toString() << action.actionTypeId().toString() << action.params();
|
||||
m_thingManager->executeAction(action);
|
||||
|
||||
}
|
||||
|
||||
void ScriptThing::init(ThingManager *thingManager)
|
||||
{
|
||||
m_thingManager = thingManager;
|
||||
connect(m_thingManager, &ThingManager::thingAdded, this, [this](Thing *newThing){
|
||||
if (newThing->id() == m_thingId) {
|
||||
qCDebug(dcScriptEngine()) << "Thing" << newThing->name() << "appeared in system";
|
||||
connectToThing();
|
||||
}
|
||||
});
|
||||
connect(m_thingManager, &ThingManager::thingStateChanged, this, [=](Thing *thing, const StateTypeId &stateTypeId, const QVariant &value, const QVariant &minValue, const QVariant &maxValue){
|
||||
Q_UNUSED(minValue)
|
||||
Q_UNUSED(maxValue)
|
||||
if (m_thingId != thing->id()) {
|
||||
return;
|
||||
}
|
||||
emit stateValueChanged(thing->thingClass().getStateType(stateTypeId).name(), value);
|
||||
});
|
||||
connect(m_thingManager, &ThingManager::eventTriggered, this, [=](const Event &event){
|
||||
if (m_thingId != event.thingId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Thing *thing = m_thingManager->findConfiguredThing(event.thingId());
|
||||
QVariantMap params;
|
||||
foreach (const Param ¶m, event.params()) {
|
||||
params.insert(param.paramTypeId().toString().remove(QRegExp("[{}]")), param.value().toByteArray());
|
||||
QString paramName = thing->thingClass().eventTypes().findById(event.eventTypeId()).paramTypes().findById(param.paramTypeId()).name();
|
||||
params.insert(paramName, param.value().toByteArray());
|
||||
}
|
||||
|
||||
// Note: Explicitly convert the params to a Json document because auto-casting from QVariantMap to the JS engine might drop some values.
|
||||
emit eventTriggered(thing->thingClass().eventTypes().findById(event.eventTypeId()).name(), QJsonDocument::fromVariant(params).toVariant().toMap());
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptThing::connectToThing()
|
||||
{
|
||||
disconnect(m_nameConnection);
|
||||
|
||||
Thing *thing = m_thingManager->findConfiguredThing(m_thingId);
|
||||
if (!thing) {
|
||||
qCDebug(dcScriptEngine()) << "Can't find thing with id" << m_thingId.toString() << "(yet)";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_nameConnection = connect(thing, &Thing::nameChanged, this, [this, thing](){
|
||||
if (thing->setupStatus() == Thing::ThingSetupStatusComplete) {
|
||||
qCDebug(dcScriptEngine()) << "Thing setup for" << thing->name() << "completed";
|
||||
emit nameChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
84
libnymea-core/scriptengine/scriptthing.h
Normal file
84
libnymea-core/scriptengine/scriptthing.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SCRIPTTHING_H
|
||||
#define SCRIPTTHING_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlParserStatus>
|
||||
#include <QUuid>
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptThing : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString thingId READ thingId WRITE setThingId NOTIFY thingIdChanged)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
public:
|
||||
explicit ScriptThing(QObject *parent = nullptr);
|
||||
explicit ScriptThing(ThingManager *thingManager, QObject *parent = nullptr);
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
|
||||
QString thingId() const;
|
||||
void setThingId(const QString &thingId);
|
||||
|
||||
QString name() const;
|
||||
|
||||
Q_INVOKABLE QVariant stateValue(const QString &stateName) const;
|
||||
|
||||
Q_INVOKABLE void setStateValue(const QString &stateName, const QVariant &value);
|
||||
Q_INVOKABLE void executeAction(const QString &actionName, const QVariantMap ¶ms);
|
||||
|
||||
signals:
|
||||
void thingIdChanged();
|
||||
void nameChanged();
|
||||
|
||||
void stateValueChanged(const QString &stateName, const QVariant &value);
|
||||
void eventTriggered(const QString &eventName, const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void init(ThingManager *thingManager);
|
||||
void connectToThing();
|
||||
|
||||
private:
|
||||
ThingId m_thingId;
|
||||
ThingManager *m_thingManager = nullptr;
|
||||
|
||||
QMetaObject::Connection m_nameConnection;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTTHING_H
|
||||
22
libnymea-core/scriptengine/scriptthingmanager.cpp
Normal file
22
libnymea-core/scriptengine/scriptthingmanager.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "scriptthingmanager.h"
|
||||
|
||||
#include <qqml.h>
|
||||
#include <QQmlEngine>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptThingManager::ScriptThingManager(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ScriptThingManager::classBegin()
|
||||
{
|
||||
m_thingManager = reinterpret_cast<ThingManager*>(qmlEngine(this)->property("thingManager").toULongLong());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
libnymea-core/scriptengine/scriptthingmanager.h
Normal file
31
libnymea-core/scriptengine/scriptthingmanager.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef SCRIPTTHINGMANAGER_H
|
||||
#define SCRIPTTHINGMANAGER_H
|
||||
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlParserStatus>
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptThingManager : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptThingManager(QObject *parent = nullptr);
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
ThingManager *m_thingManager = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCRIPTTHINGMANAGER_H
|
||||
162
libnymea-core/scriptengine/scriptthings.cpp
Normal file
162
libnymea-core/scriptengine/scriptthings.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "scriptthings.h"
|
||||
#include "scriptthing.h"
|
||||
|
||||
#include <qqml.h>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
ScriptThings::ScriptThings(QObject *parent)
|
||||
: QSortFilterProxyModel{parent}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ScriptThings::classBegin()
|
||||
{
|
||||
m_thingManager = reinterpret_cast<ThingManager*>(qmlEngine(this)->property("thingManager").toULongLong());
|
||||
m_model = new ThingsModel(m_thingManager, this);
|
||||
setSourceModel(m_model);
|
||||
|
||||
connect(m_thingManager, &ThingManager::thingAdded, this, [this](Thing *newThing){
|
||||
emit thingAdded(newThing->id().toString());
|
||||
emit countChanged();
|
||||
});
|
||||
connect(m_thingManager, &ThingManager::thingRemoved, this, [this](const ThingId &thingId){
|
||||
emit thingRemoved(thingId.toString());
|
||||
emit countChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptThings::componentComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString ScriptThings::filterInterface() const
|
||||
{
|
||||
return m_filterInterface;
|
||||
}
|
||||
|
||||
void ScriptThings::setFilterInterface(const QString &filterInterface)
|
||||
{
|
||||
if (m_filterInterface != filterInterface) {
|
||||
m_filterInterface = filterInterface;
|
||||
emit filterInterfaceChanged();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptThing *ScriptThings::get(int index) const
|
||||
{
|
||||
Thing *thing = m_model->get(mapToSource(this->index(index, 0)).row());
|
||||
if (!thing) {
|
||||
return nullptr;
|
||||
}
|
||||
ScriptThing *scriptThing = new ScriptThing(m_thingManager);
|
||||
QQmlEngine::setObjectOwnership(scriptThing, QQmlEngine::JavaScriptOwnership);
|
||||
scriptThing->setThingId(thing->id().toString());
|
||||
return scriptThing;
|
||||
|
||||
}
|
||||
|
||||
ScriptThing *ScriptThings::getThing(const QUuid &thingId) const
|
||||
{
|
||||
Thing *thing = m_model->getThing(thingId);
|
||||
if (!thing) {
|
||||
return nullptr;
|
||||
}
|
||||
ScriptThing *scriptThing = new ScriptThing(m_thingManager);
|
||||
QQmlEngine::setObjectOwnership(scriptThing, QQmlEngine::JavaScriptOwnership);
|
||||
scriptThing->setThingId(thing->id().toString());
|
||||
return scriptThing;
|
||||
}
|
||||
|
||||
bool ScriptThings::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
Q_UNUSED(sourceParent)
|
||||
Thing *thing = m_model->get(sourceRow);
|
||||
if (!m_filterInterface.isEmpty() && !thing->thingClass().interfaces().contains(m_filterInterface)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ThingsModel::ThingsModel(ThingManager *thingManager, QObject *parent):
|
||||
QAbstractListModel(parent),
|
||||
m_thingManager(thingManager)
|
||||
{
|
||||
}
|
||||
|
||||
int ThingsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_thingManager->configuredThings().count();
|
||||
}
|
||||
|
||||
QVariant ThingsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case RoleId:
|
||||
return m_thingManager->configuredThings().at(index.row())->id();
|
||||
case RoleName:
|
||||
return m_thingManager->configuredThings().at(index.row())->name();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ThingsModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{RoleId, "thingId"},
|
||||
{RoleName, "thingName"}
|
||||
};
|
||||
}
|
||||
|
||||
Thing *ThingsModel::get(int index) const
|
||||
{
|
||||
return m_thingManager->configuredThings().at(index);
|
||||
}
|
||||
|
||||
Thing *ThingsModel::getThing(const QUuid &thingId) const
|
||||
{
|
||||
return m_thingManager->findConfiguredThing(thingId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
110
libnymea-core/scriptengine/scriptthings.h
Normal file
110
libnymea-core/scriptengine/scriptthings.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SCRIPTTHINGS_H
|
||||
#define SCRIPTTHINGS_H
|
||||
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QQmlParserStatus>
|
||||
|
||||
|
||||
namespace nymeaserver {
|
||||
namespace scriptengine {
|
||||
|
||||
class ScriptThing;
|
||||
class ThingsModel;
|
||||
|
||||
|
||||
class ScriptThings : public QSortFilterProxyModel, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
Q_PROPERTY(QString filterInterface READ filterInterface WRITE setFilterInterface NOTIFY filterInterfaceChanged)
|
||||
|
||||
public:
|
||||
explicit ScriptThings(QObject *parent = nullptr);
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
|
||||
QString filterInterface() const;
|
||||
void setFilterInterface(const QString &filterInterface);
|
||||
|
||||
Q_INVOKABLE nymeaserver::scriptengine::ScriptThing *get(int index) const;
|
||||
Q_INVOKABLE nymeaserver::scriptengine::ScriptThing *getThing(const QUuid &thingId) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void filterInterfaceChanged();
|
||||
void thingAdded(const QString &thingId);
|
||||
void thingRemoved(const QString &thingId);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
private:
|
||||
ThingManager *m_thingManager = nullptr;
|
||||
ThingsModel *m_model = nullptr;
|
||||
|
||||
QString m_filterInterface;
|
||||
};
|
||||
|
||||
class ThingsModel: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
RoleId,
|
||||
RoleName
|
||||
};
|
||||
ThingsModel(ThingManager *thingManager, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Thing *get(int index) const;
|
||||
Thing *getThing(const QUuid &thingId) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
ThingManager *m_thingManager = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif // SCRIPTTHINGS_H
|
||||
7
libnymea-core/scriptengine/scriptthingsfilter.cpp
Normal file
7
libnymea-core/scriptengine/scriptthingsfilter.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "scriptthingsfilter.h"
|
||||
|
||||
ScriptThingsFilter::ScriptThingsFilter(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
|
||||
}
|
||||
17
libnymea-core/scriptengine/scriptthingsfilter.h
Normal file
17
libnymea-core/scriptengine/scriptthingsfilter.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef SCRIPTTHINGSFILTER_H
|
||||
#define SCRIPTTHINGSFILTER_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class ScriptThingsFilter : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY()
|
||||
public:
|
||||
explicit ScriptThingsFilter(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // SCRIPTTHINGSFILTER_H
|
||||
@ -50,7 +50,6 @@ NYMEA_LOGGING_CATEGORY(dcExperiences, "Experiences")
|
||||
NYMEA_LOGGING_CATEGORY(dcTimeManager, "TimeManager")
|
||||
NYMEA_LOGGING_CATEGORY(dcRuleEngine, "RuleEngine")
|
||||
NYMEA_LOGGING_CATEGORY(dcRuleEngineDebug, "RuleEngineDebug")
|
||||
NYMEA_LOGGING_CATEGORY(dcScriptEngine, "ScriptEngine")
|
||||
NYMEA_LOGGING_CATEGORY(dcHardware, "Hardware")
|
||||
NYMEA_LOGGING_CATEGORY(dcLogEngine, "LogEngine")
|
||||
NYMEA_LOGGING_CATEGORY(dcServerManager, "ServerManager")
|
||||
|
||||
@ -58,7 +58,6 @@ Q_DECLARE_LOGGING_CATEGORY(dcExperiences)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcTimeManager)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRuleEngine)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcRuleEngineDebug)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcScriptEngine)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcHardware)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcLogEngine)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcServerManager)
|
||||
|
||||
@ -50,6 +50,11 @@ void TestHelper::logStateChange(const QString &thingId, const QString &stateId,
|
||||
emit stateChangeLogged(ThingId(thingId), stateId, value);
|
||||
}
|
||||
|
||||
void TestHelper::setTestResult(bool success)
|
||||
{
|
||||
emit testResult(success);
|
||||
}
|
||||
|
||||
TestHelper::TestHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
|
||||
@ -34,12 +34,17 @@ public:
|
||||
Q_INVOKABLE void logEvent(const QString &thingId, const QString &eventId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void logStateChange(const QString &thingId, const QString &stateId, const QVariant &value);
|
||||
|
||||
Q_INVOKABLE void setTestResult(bool success);
|
||||
|
||||
signals:
|
||||
void setState(const QVariant &value);
|
||||
void executeAction(const QVariantMap ¶ms);
|
||||
|
||||
void eventLogged(const ThingId &thingId, const QString &eventId, const QVariantMap ¶ms);
|
||||
void stateChangeLogged(const ThingId &thingId, const QString stateId, const QVariant &value);
|
||||
|
||||
void testResult(bool success);
|
||||
|
||||
private:
|
||||
explicit TestHelper(QObject *parent = nullptr);
|
||||
static TestHelper* s_instance;
|
||||
|
||||
@ -74,6 +74,13 @@ private slots:
|
||||
void testInterfaceEvent();
|
||||
void testInterfaceState();
|
||||
void testInterfaceAction();
|
||||
|
||||
void testScriptThingAction();
|
||||
void testScriptThingReadState();
|
||||
void testScriptThingWriteState();
|
||||
void testScriptThingEvent();
|
||||
|
||||
void testThingsFindThing();
|
||||
};
|
||||
|
||||
|
||||
@ -518,6 +525,180 @@ void TestScripts::testInterfaceAction()
|
||||
|
||||
}
|
||||
|
||||
void TestScripts::testScriptThingAction()
|
||||
{
|
||||
QString script = QString("import QtQuick 2.0\n"
|
||||
"import nymea 1.0\n"
|
||||
"Item {\n"
|
||||
" Thing {\n"
|
||||
" id: thing\n"
|
||||
" thingId: \"%1\"\n"
|
||||
" }\n"
|
||||
" Connections {\n"
|
||||
" target: TestHelper\n"
|
||||
" onExecuteAction: {\n"
|
||||
" thing.executeAction(\"%2\", params)\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n").arg(m_mockThingId.toString()).arg("power");
|
||||
|
||||
qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script);
|
||||
ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestAction", script.toUtf8());
|
||||
QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError);
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance()->thingManager(), &ThingManager::thingStateChanged);
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("power", true);
|
||||
TestHelper::instance()->executeAction(params);
|
||||
|
||||
spy.wait(1);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().at(0).value<Thing*>()->id(), m_mockThingId);
|
||||
QCOMPARE(spy.first().at(1).value<StateTypeId>(), mockPowerStateTypeId);
|
||||
QCOMPARE(spy.first().at(2).toBool(), true);
|
||||
|
||||
}
|
||||
|
||||
void TestScripts::testScriptThingReadState()
|
||||
{
|
||||
QString script = QString("import QtQuick 2.0\n"
|
||||
"import nymea 1.0\n"
|
||||
"Item {\n"
|
||||
" Thing {\n"
|
||||
" thingId: \"%1\"\n"
|
||||
" onStateValueChanged: {\n"
|
||||
" TestHelper.logStateChange(thingId, stateName, value);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n").arg(m_mockThingId.toString()).arg("power");
|
||||
|
||||
qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script);
|
||||
ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8());
|
||||
QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError);
|
||||
|
||||
QSignalSpy spy(TestHelper::instance(), &TestHelper::stateChangeLogged);
|
||||
|
||||
// Generate state change
|
||||
Action action(mockPowerActionTypeId, m_mockThingId);
|
||||
action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, true));
|
||||
NymeaCore::instance()->thingManager()->executeAction(action);
|
||||
|
||||
spy.wait(1);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().at(0).value<ThingId>(), m_mockThingId);
|
||||
QCOMPARE(spy.first().at(1).toString(), QString("power"));
|
||||
QCOMPARE(spy.first().at(2).toBool(), true);
|
||||
|
||||
}
|
||||
|
||||
void TestScripts::testScriptThingWriteState()
|
||||
{
|
||||
QString script = QString("import QtQuick 2.0\n"
|
||||
"import nymea 1.0\n"
|
||||
"Item {\n"
|
||||
" Thing {\n"
|
||||
" id: thing\n"
|
||||
" thingId: \"%1\"\n"
|
||||
" }\n"
|
||||
" Connections {\n"
|
||||
" target: TestHelper\n"
|
||||
" onSetState: {\n"
|
||||
" thing.setStateValue(\"%2\", value)\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n").arg(m_mockThingId.toString()).arg("power");
|
||||
|
||||
qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script);
|
||||
ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8());
|
||||
QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError);
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance()->thingManager(), &ThingManager::thingStateChanged);
|
||||
|
||||
TestHelper::instance()->setState(true);
|
||||
|
||||
spy.wait(1);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().at(0).value<Thing*>()->id(), m_mockThingId);
|
||||
QCOMPARE(spy.first().at(1).value<StateTypeId>(), mockPowerStateTypeId);
|
||||
QCOMPARE(spy.first().at(2).toBool(), true);
|
||||
|
||||
}
|
||||
|
||||
void TestScripts::testScriptThingEvent()
|
||||
{
|
||||
QString script = QString("import QtQuick 2.0\n"
|
||||
"import nymea 1.0\n"
|
||||
"Item {\n"
|
||||
" Thing {\n"
|
||||
" thingId: \"%1\"\n"
|
||||
" onEventTriggered: {\n"
|
||||
" TestHelper.logEvent(thingId, eventName, params);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n").arg(m_mockThingId.toString());
|
||||
|
||||
qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script);
|
||||
ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestEvent", script.toUtf8());
|
||||
QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError);
|
||||
|
||||
QSignalSpy spy(TestHelper::instance(), &TestHelper::eventLogged);
|
||||
|
||||
// trigger event in mock device
|
||||
Thing* thing = NymeaCore::instance()->thingManager()->findConfiguredThing(m_mockThingId);
|
||||
int port = thing->paramValue(mockThingHttpportParamTypeId).toInt();
|
||||
QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2&%3=%4")
|
||||
.arg(port)
|
||||
.arg(mockEvent2EventTypeId.toString())
|
||||
.arg(mockEvent2EventIntParamParamTypeId.toString())
|
||||
.arg(10)));
|
||||
QNetworkAccessManager nam;
|
||||
QNetworkReply *r = nam.get(request);
|
||||
connect(r, &QNetworkReply::finished, r, &QNetworkReply::deleteLater);
|
||||
|
||||
spy.wait();
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().at(0).value<ThingId>(), m_mockThingId);
|
||||
QCOMPARE(spy.first().at(1).toString(), QString("event2"));
|
||||
QVariantMap expectedParams;
|
||||
expectedParams.insert(mockEvent2EventIntParamParamTypeId.toString().remove(QRegExp("[{}]")), 10);
|
||||
expectedParams.insert("intParam", 10);
|
||||
QCOMPARE(spy.first().at(2).toMap(), expectedParams);
|
||||
|
||||
}
|
||||
|
||||
void TestScripts::testThingsFindThing()
|
||||
{
|
||||
QSignalSpy spy(TestHelper::instance(), &TestHelper::testResult);
|
||||
|
||||
QString script = QString("import QtQuick 2.0\n"
|
||||
"import nymea 1.0\n"
|
||||
"Item {\n"
|
||||
" id: root\n"
|
||||
" property string thingId: \"%1\"\n"
|
||||
" Things {\n"
|
||||
" id: things\n"
|
||||
" }\n"
|
||||
" Component.onCompleted: {\n"
|
||||
" var thing = things.getThing(root.thingId)\n"
|
||||
" TestHelper.setTestResult(thing.thingId == root.thingId);\n"
|
||||
" }\n"
|
||||
"}\n").arg(m_mockThingId.toString());
|
||||
|
||||
qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script);
|
||||
ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestEvent", script.toUtf8());
|
||||
QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().at(0).toBool(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "testscripts.moc"
|
||||
QTEST_MAIN(TestScripts)
|
||||
|
||||
Reference in New Issue
Block a user