mirror of https://github.com/nymea/nymea.git
A little more work on browser item support for rules
parent
4e7557f964
commit
0fb42681af
|
|
@ -184,6 +184,7 @@ void JsonTypes::init()
|
|||
s_ruleAction.insert("o:actionTypeId", basicTypeToString(Uuid));
|
||||
s_ruleAction.insert("o:interface", basicTypeToString(String));
|
||||
s_ruleAction.insert("o:interfaceAction", basicTypeToString(String));
|
||||
s_ruleAction.insert("o:browserItemId", basicTypeToString(String));
|
||||
s_ruleAction.insert("o:ruleActionParams", QVariantList() << ruleActionParamRef());
|
||||
|
||||
// RuleActionParam
|
||||
|
|
@ -617,8 +618,11 @@ QVariantMap JsonTypes::packRuleAction(const RuleAction &ruleAction)
|
|||
{
|
||||
QVariantMap variant;
|
||||
if (ruleAction.type() == RuleAction::TypeDevice) {
|
||||
variant.insert("actionTypeId", ruleAction.actionTypeId().toString());
|
||||
variant.insert("deviceId", ruleAction.deviceId().toString());
|
||||
variant.insert("actionTypeId", ruleAction.actionTypeId().toString());
|
||||
} else if (ruleAction.type() == RuleAction::TypeBrowser) {
|
||||
variant.insert("deviceId", ruleAction.deviceId().toString());
|
||||
variant.insert("browserItemId", ruleAction.browserItemId());
|
||||
} else {
|
||||
variant.insert("interface", ruleAction.interface());
|
||||
variant.insert("interfaceAction", ruleAction.interfaceAction());
|
||||
|
|
@ -1500,10 +1504,13 @@ RuleAction JsonTypes::unpackRuleAction(const QVariantMap &ruleActionMap)
|
|||
DeviceId actionDeviceId(ruleActionMap.value("deviceId").toString());
|
||||
QString interface = ruleActionMap.value("interface").toString();
|
||||
QString interfaceAction = ruleActionMap.value("interfaceAction").toString();
|
||||
QString browserItemId = ruleActionMap.value("browserItemId").toString();
|
||||
RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(ruleActionMap.value("ruleActionParams").toList());
|
||||
|
||||
if (!actionTypeId.isNull() && !actionDeviceId.isNull()) {
|
||||
if (!actionDeviceId.isNull() && !actionTypeId.isNull()) {
|
||||
return RuleAction(actionTypeId, actionDeviceId, actionParamList);
|
||||
} else if (!actionDeviceId.isNull() && !browserItemId.isNull()) {
|
||||
return RuleAction(actionDeviceId, browserItemId);
|
||||
}
|
||||
return RuleAction(interface, interfaceAction, actionParamList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ RESOURCES += $$top_srcdir/icons.qrc \
|
|||
HEADERS += nymeacore.h \
|
||||
devices/devicemanagerimplementation.h \
|
||||
devices/translator.h \
|
||||
devices/stateevaluator.h \
|
||||
ruleengine/ruleengine.h \
|
||||
ruleengine/rule.h \
|
||||
ruleengine/stateevaluator.h \
|
||||
ruleengine/ruleaction.h \
|
||||
ruleengine/ruleactionparam.h \
|
||||
transportinterface.h \
|
||||
nymeaconfiguration.h \
|
||||
servermanager.h \
|
||||
|
|
@ -102,9 +104,11 @@ HEADERS += nymeacore.h \
|
|||
SOURCES += nymeacore.cpp \
|
||||
devices/devicemanagerimplementation.cpp \
|
||||
devices/translator.cpp \
|
||||
devices/stateevaluator.cpp \
|
||||
ruleengine/ruleengine.cpp \
|
||||
ruleengine/rule.cpp \
|
||||
ruleengine/stateevaluator.cpp \
|
||||
ruleengine/ruleaction.cpp \
|
||||
ruleengine/ruleactionparam.cpp \
|
||||
transportinterface.cpp \
|
||||
nymeaconfiguration.cpp \
|
||||
servermanager.cpp \
|
||||
|
|
|
|||
|
|
@ -478,9 +478,14 @@ Device::DeviceError NymeaCore::executeBrowserItemAction(const BrowserItemAction
|
|||
void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
||||
{
|
||||
QList<Action> actions;
|
||||
QList<BrowserAction> browserActions;
|
||||
foreach (const RuleAction &ruleAction, ruleActions) {
|
||||
if (ruleAction.type() == RuleAction::TypeDevice) {
|
||||
Device *device = m_deviceManager->findConfiguredDevice(ruleAction.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine()) << "Unable to find device" << ruleAction.deviceId() << "for rule action" << ruleAction;
|
||||
continue;
|
||||
}
|
||||
ActionTypeId actionTypeId = ruleAction.actionTypeId();
|
||||
ParamList params;
|
||||
bool ok = true;
|
||||
|
|
@ -510,6 +515,14 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
|||
Action action(actionTypeId, device->id());
|
||||
action.setParams(params);
|
||||
actions.append(action);
|
||||
} else if (ruleAction.type() == RuleAction::TypeBrowser) {
|
||||
Device *device = m_deviceManager->findConfiguredDevice(ruleAction.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine()) << "Unable to find device" << ruleAction.deviceId() << "for rule action" << ruleAction;
|
||||
continue;
|
||||
}
|
||||
BrowserAction browserAction(ruleAction.deviceId(), ruleAction.browserItemId());
|
||||
browserActions.append(browserAction);
|
||||
} else {
|
||||
QList<Device*> devices = m_deviceManager->findConfiguredDevices(ruleAction.interface());
|
||||
foreach (Device* device, devices) {
|
||||
|
|
@ -581,6 +594,25 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
|||
// if (status != Device::DeviceErrorAsync)
|
||||
// m_logger->logAction(action, status == Device::DeviceErrorNoError ? Logging::LoggingLevelInfo : Logging::LoggingLevelAlert, status);
|
||||
}
|
||||
|
||||
foreach (const BrowserAction &browserAction, browserActions) {
|
||||
Device::DeviceError status = executeBrowserItem(browserAction);
|
||||
switch(status) {
|
||||
case Device::DeviceErrorNoError:
|
||||
break;
|
||||
case Device::DeviceErrorSetupFailed:
|
||||
qCWarning(dcRuleEngine) << "Error executing action. Device setup failed.";
|
||||
break;
|
||||
case Device::DeviceErrorAsync:
|
||||
qCDebug(dcRuleEngine) << "Executing asynchronous action.";
|
||||
break;
|
||||
case Device::DeviceErrorInvalidParameter:
|
||||
qCWarning(dcRuleEngine) << "Error executing action. Invalid action parameter.";
|
||||
break;
|
||||
default:
|
||||
qCWarning(dcRuleEngine) << "Error executing action:" << status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! Calls the metheod RuleEngine::removeRule(\a id).
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ RuleAction::Type RuleAction::type() const
|
|||
if (!m_deviceId.isNull() && !m_actionTypeId.isNull()) {
|
||||
return TypeDevice;
|
||||
}
|
||||
if (!m_deviceId.isNull() && m_browserItemId.isEmpty()) {
|
||||
if (!m_deviceId.isNull() && !m_browserItemId.isEmpty()) {
|
||||
return TypeBrowser;
|
||||
}
|
||||
if (!m_interface.isEmpty() && !m_interfaceAction.isEmpty()) {
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
#define RULEACTION_H
|
||||
|
||||
#include "libnymea.h"
|
||||
#include "action.h"
|
||||
#include "types/action.h"
|
||||
#include "types/browseritemaction.h"
|
||||
#include "ruleactionparam.h"
|
||||
#include "browseritemaction.h"
|
||||
|
||||
class LIBNYMEA_EXPORT RuleAction
|
||||
{
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "param.h"
|
||||
#include "types/param.h"
|
||||
#include "libnymea.h"
|
||||
#include "typeutils.h"
|
||||
|
||||
|
|
@ -912,7 +912,7 @@ bool RuleEngine::containsState(const StateEvaluator &stateEvaluator, const Event
|
|||
RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction, const Rule &rule)
|
||||
{
|
||||
if (!ruleAction.isValid()) {
|
||||
qWarning(dcRuleEngine()) << "Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction";
|
||||
qWarning(dcRuleEngine()) << "Action is incomplete. It must have either deviceId and actionTypeId/browserItemId, or interface and interfaceAction:" << ruleAction;
|
||||
return RuleErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
|
|
@ -920,7 +920,7 @@ RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction,
|
|||
if (ruleAction.type() == RuleAction::TypeDevice) {
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleAction.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for action with actionTypeId" << ruleAction.actionTypeId();
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. No configured device with ID" << ruleAction.deviceId();
|
||||
return RuleErrorDeviceNotFound;
|
||||
}
|
||||
|
||||
|
|
@ -942,10 +942,23 @@ RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction,
|
|||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << ruleAction.interfaceAction();
|
||||
return RuleError::RuleErrorActionTypeNotFound;
|
||||
}
|
||||
} else if (ruleAction.type() == RuleAction::TypeBrowser) {
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleAction.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. No configured device with ID" << ruleAction.deviceId();
|
||||
return RuleErrorDeviceNotFound;
|
||||
}
|
||||
if (ruleAction.browserItemId().isEmpty()) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule with empty browserItemId";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
|
||||
} else {
|
||||
return RuleErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
// Not all rule actions might have an actiontype (e.g. browser item executions)
|
||||
if (!actionType.id().isNull()) {
|
||||
// Verify given params
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
RuleError ruleActionParamError = checkRuleActionParam(ruleActionParam, actionType, rule);
|
||||
|
|
@ -968,6 +981,7 @@ RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction,
|
|||
return RuleErrorMissingParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
|
@ -1190,66 +1204,54 @@ void RuleEngine::saveRule(const Rule &rule)
|
|||
rule.stateEvaluator().dumpToSettings(settings, "stateEvaluator");
|
||||
|
||||
// Save ruleActions
|
||||
int i = 0;
|
||||
settings.beginGroup("ruleActions");
|
||||
foreach (const RuleAction &action, rule.actions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
if (!action.deviceId().isNull() && !action.actionTypeId().isNull()) {
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
} else {
|
||||
settings.setValue("interface", action.interface());
|
||||
settings.setValue("interfaceAction", action.interfaceAction());
|
||||
}
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
if (!param.paramTypeId().isNull()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.paramTypeId().toString());
|
||||
} else {
|
||||
settings.beginGroup("RuleActionParam-" + param.paramName());
|
||||
}
|
||||
settings.setValue("valueType", static_cast<int>(param.value().type()));
|
||||
settings.setValue("value", param.value());
|
||||
if (param.isEventBased()) {
|
||||
settings.setValue("eventTypeId", param.eventTypeId().toString());
|
||||
settings.setValue("eventParamTypeId", param.eventParamTypeId());
|
||||
} else if (param.isStateBased()) {
|
||||
settings.setValue("stateDeviceId", param.stateDeviceId().toString());
|
||||
settings.setValue("stateTypeId", param.stateTypeId());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
}
|
||||
saveRuleActions(&settings, rule.actions());
|
||||
settings.endGroup();
|
||||
|
||||
// Save ruleExitActions
|
||||
settings.beginGroup("ruleExitActions");
|
||||
i = 0;
|
||||
foreach (const RuleAction &action, rule.exitActions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
if (!action.deviceId().isNull() && !action.actionTypeId().isNull()) {
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
saveRuleActions(&settings, rule.exitActions());
|
||||
settings.endGroup();
|
||||
qCDebug(dcRuleEngineDebug()) << "Saved rule to config:" << rule;
|
||||
}
|
||||
|
||||
void RuleEngine::saveRuleActions(NymeaSettings *settings, const QList<RuleAction> &ruleActions)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (const RuleAction &action, ruleActions) {
|
||||
settings->beginGroup(QString::number(i));
|
||||
if (action.type() == RuleAction::TypeDevice) {
|
||||
settings->setValue("deviceId", action.deviceId().toString());
|
||||
settings->setValue("actionTypeId", action.actionTypeId().toString());
|
||||
} else if (action.type() == RuleAction::TypeBrowser) {
|
||||
settings->setValue("deviceId", action.deviceId().toString());
|
||||
settings->setValue("browserItemId", action.browserItemId());
|
||||
} else if (action.type() == RuleAction::TypeInterface){
|
||||
settings->setValue("interface", action.interface());
|
||||
settings->setValue("interfaceAction", action.interfaceAction());
|
||||
} else {
|
||||
settings.setValue("interface", action.interface());
|
||||
settings.setValue("interfaceAction", action.interfaceAction());
|
||||
Q_ASSERT_X(false, "RuleEngine::saveRule", "Unhandled rule action type.");
|
||||
}
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
if (!param.paramTypeId().isNull()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.paramTypeId().toString());
|
||||
settings->beginGroup("RuleActionParam-" + param.paramTypeId().toString());
|
||||
} else {
|
||||
settings.beginGroup("RuleActionParam-" + param.paramName());
|
||||
settings->beginGroup("RuleActionParam-" + param.paramName());
|
||||
}
|
||||
settings.setValue("valueType", static_cast<int>(param.value().type()));
|
||||
settings.setValue("value", param.value());
|
||||
settings.endGroup();
|
||||
settings->setValue("valueType", static_cast<int>(param.value().type()));
|
||||
settings->setValue("value", param.value());
|
||||
if (param.isEventBased()) {
|
||||
settings->setValue("eventTypeId", param.eventTypeId().toString());
|
||||
settings->setValue("eventParamTypeId", param.eventParamTypeId());
|
||||
} else if (param.isStateBased()) {
|
||||
settings->setValue("stateDeviceId", param.stateDeviceId().toString());
|
||||
settings->setValue("stateTypeId", param.stateTypeId());
|
||||
}
|
||||
settings->endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
settings->endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
qCDebug(dcRuleEngineDebug()) << "Saved rule to config:" << rule;
|
||||
}
|
||||
|
||||
void RuleEngine::init()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QUuid>
|
||||
#include <QSettings>
|
||||
|
||||
namespace nymeaserver {
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ private:
|
|||
|
||||
void appendRule(const Rule &rule);
|
||||
void saveRule(const Rule &rule);
|
||||
void saveRuleActions(NymeaSettings *settings, const QList<RuleAction> &ruleActions);
|
||||
|
||||
private:
|
||||
QList<RuleId> m_ruleIds; // Keeping a list of RuleIds to keep sorting order...
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ HEADERS += \
|
|||
types/paramtype.h \
|
||||
types/param.h \
|
||||
types/paramdescriptor.h \
|
||||
types/ruleaction.h \
|
||||
types/ruleactionparam.h \
|
||||
types/statedescriptor.h \
|
||||
types/interface.h \
|
||||
hardwareresource.h \
|
||||
|
|
@ -130,8 +128,6 @@ SOURCES += \
|
|||
types/paramtype.cpp \
|
||||
types/param.cpp \
|
||||
types/paramdescriptor.cpp \
|
||||
types/ruleaction.cpp \
|
||||
types/ruleactionparam.cpp \
|
||||
types/statedescriptor.cpp \
|
||||
types/interface.cpp \
|
||||
hardwareresource.cpp \
|
||||
|
|
|
|||
Loading…
Reference in New Issue