mirror of https://github.com/nymea/nymea.git
more work on rules
disallow removing a device if a rule still refers to it unless parameters contain information on what to do with those rules.pull/135/head
parent
cd67ab567b
commit
be90f47f63
|
|
@ -78,9 +78,37 @@ QList<DeviceClass> GuhCore::supportedDevices(const VendorId &vendorId) const
|
|||
return m_deviceManager->supportedDevices(vendorId);
|
||||
}
|
||||
|
||||
QPair<DeviceManager::DeviceError, QString> GuhCore::removeConfiguredDevice(const DeviceId &deviceId)
|
||||
QPair<DeviceManager::DeviceError, QString> GuhCore::removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList)
|
||||
{
|
||||
// TODO: make sure we don't remove a device and keep stale rules around...
|
||||
QHash<RuleId, RuleEngine::RemovePolicy> toBeChanged;
|
||||
QList<RuleId> unhandledRules;
|
||||
foreach (const RuleId &ruleId, m_ruleEngine->findRules(deviceId)) {
|
||||
bool found = false;
|
||||
foreach (const RuleId &policyRuleId, removePolicyList.keys()) {
|
||||
if (ruleId == policyRuleId) {
|
||||
found = true;
|
||||
toBeChanged.insert(ruleId, removePolicyList.value(ruleId));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
unhandledRules.append(ruleId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unhandledRules.isEmpty()) {
|
||||
return qMakePair<DeviceManager::DeviceError, QString>(DeviceManager::DeviceErrorMissingParameter, "There are unhandled rules which depend on this device.");
|
||||
}
|
||||
|
||||
// Update the rules...
|
||||
foreach (const RuleId &ruleId, toBeChanged.keys()) {
|
||||
if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyCascade) {
|
||||
m_ruleEngine->removeRule(ruleId);
|
||||
} else if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyUpdate){
|
||||
m_ruleEngine->removeDeviceFromRule(ruleId, deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
return m_deviceManager->removeConfiguredDevice(deviceId);
|
||||
}
|
||||
|
||||
|
|
@ -144,6 +172,16 @@ QList<Rule> GuhCore::rules() const
|
|||
return m_ruleEngine->rules();
|
||||
}
|
||||
|
||||
QList<RuleId> GuhCore::ruleIds() const
|
||||
{
|
||||
return m_ruleEngine->ruleIds();
|
||||
}
|
||||
|
||||
Rule GuhCore::findRule(const RuleId &ruleId)
|
||||
{
|
||||
return m_ruleEngine->findRule(ruleId);
|
||||
}
|
||||
|
||||
RuleEngine::RuleError GuhCore::addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList)
|
||||
{
|
||||
return m_ruleEngine->addRule(id, eventDescriptorList, actionList);
|
||||
|
|
@ -154,6 +192,11 @@ RuleEngine::RuleError GuhCore::removeRule(const RuleId &id)
|
|||
return m_ruleEngine->removeRule(id);
|
||||
}
|
||||
|
||||
QList<RuleId> GuhCore::findRules(const DeviceId &deviceId)
|
||||
{
|
||||
return m_ruleEngine->findRules(deviceId);
|
||||
}
|
||||
|
||||
/*! Returns a pointer to the \l{DeviceManager} instance owned by GuhCore.*/
|
||||
DeviceManager *GuhCore::deviceManager() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
QList<Device*> configuredDevices() const;
|
||||
Device *findConfiguredDevice(const DeviceId &deviceId) const;
|
||||
QList<Device*> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
|
||||
QPair<DeviceManager::DeviceError, QString> removeConfiguredDevice(const DeviceId &deviceId);
|
||||
QPair<DeviceManager::DeviceError, QString> removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList);
|
||||
|
||||
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId);
|
||||
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const QList<Param> ¶ms);
|
||||
|
|
@ -64,8 +64,11 @@ public:
|
|||
QPair<DeviceManager::DeviceError, QString> executeAction(const Action &action);
|
||||
|
||||
QList<Rule> rules() const;
|
||||
QList<RuleId> ruleIds() const;
|
||||
Rule findRule(const RuleId &ruleId);
|
||||
RuleEngine::RuleError addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList);
|
||||
RuleEngine::RuleError removeRule(const RuleId &id);
|
||||
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||
|
||||
signals:
|
||||
void eventTriggered(const Event &event);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,12 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||
params.clear(); returns.clear();
|
||||
setDescription("RemoveConfiguredDevice", "Remove a device from the system.");
|
||||
params.insert("deviceId", "uuid");
|
||||
QVariantList removePolicyList;
|
||||
QVariantMap policy;
|
||||
policy.insert("ruleId", "uuid");
|
||||
policy.insert("policy", JsonTypes::removePolicyTypesRef());
|
||||
removePolicyList.append(policy);
|
||||
params.insert("o:removePolicyList", removePolicyList);
|
||||
setParams("RemoveConfiguredDevice", params);
|
||||
returns.insert("success", "bool");
|
||||
returns.insert("errorMessage", "string");
|
||||
|
|
@ -480,8 +486,16 @@ JsonReply* DeviceHandler::GetConfiguredDevices(const QVariantMap ¶ms) const
|
|||
|
||||
JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms)
|
||||
{
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QHash<RuleId, RuleEngine::RemovePolicy> removePolicyList;
|
||||
foreach (const QVariant &variant, params.value("removePolicyList").toList()) {
|
||||
RuleId ruleId = RuleId(variant.toMap().value("ruleId").toString());
|
||||
RuleEngine::RemovePolicy policy = variant.toMap().value("policy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate;
|
||||
removePolicyList.insert(ruleId, policy);
|
||||
}
|
||||
|
||||
QVariantMap returns;
|
||||
QPair<DeviceManager::DeviceError, QString> status = GuhCore::instance()->removeConfiguredDevice(DeviceId(params.value("deviceId").toString()));
|
||||
QPair<DeviceManager::DeviceError, QString> status = GuhCore::instance()->removeConfiguredDevice(deviceId, removePolicyList);
|
||||
switch(status.first) {
|
||||
case DeviceManager::DeviceErrorNoError:
|
||||
returns.insert("success", true);
|
||||
|
|
@ -491,6 +505,10 @@ JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms)
|
|||
returns.insert("success", false);
|
||||
returns.insert("errorMessage", QString("No such device: %1").arg(status.second));
|
||||
break;
|
||||
case DeviceManager::DeviceErrorMissingParameter:
|
||||
returns.insert("success", false);
|
||||
returns.insert("errorMessage", QString("Missing Parameter: %1").arg(status.second));
|
||||
break;
|
||||
default:
|
||||
returns.insert("success", false);
|
||||
returns.insert("errorMessage", "Unknown error.");
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QStringList>
|
||||
|
||||
#define JSON_PROTOCOL_VERSION 2
|
||||
#define JSON_PROTOCOL_VERSION 3
|
||||
|
||||
JsonRPCServer::JsonRPCServer(QObject *parent):
|
||||
JsonHandler(parent),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ QVariantList JsonTypes::s_stateOperatorTypes;
|
|||
QVariantList JsonTypes::s_valueOperatorTypes;
|
||||
QVariantList JsonTypes::s_createMethodTypes;
|
||||
QVariantList JsonTypes::s_setupMethodTypes;
|
||||
QVariantList JsonTypes::s_removePolicyTypes;
|
||||
|
||||
QVariantMap JsonTypes::s_paramType;
|
||||
QVariantMap JsonTypes::s_param;
|
||||
|
|
@ -60,6 +61,7 @@ void JsonTypes::init()
|
|||
s_valueOperatorTypes << "OperatorTypeEquals" << "OperatorTypeNotEquals" << "OperatorTypeLess" << "OperatorTypeGreater" << "OperatorTypeLessThan" << "OperatorTypeGreaterThan";
|
||||
s_createMethodTypes << "CreateMethodUser" << "CreateMethodAuto" << "CreateMethodDiscovery";
|
||||
s_setupMethodTypes << "SetupMethodJustAdd" << "SetupMethodDisplayPin" << "SetupMethodEnterPin" << "SetupMethodPushButton";
|
||||
s_removePolicyTypes << "RemovePolicyCascade" << "RemovePolicyUpdate";
|
||||
|
||||
// ParamType
|
||||
s_paramType.insert("name", "string");
|
||||
|
|
@ -180,6 +182,7 @@ QVariantMap JsonTypes::allTypes()
|
|||
allTypes.insert("SetupMethodType", setupMethodTypes());
|
||||
allTypes.insert("ValueOperatorType", valueOperatorTypes());
|
||||
allTypes.insert("StateOperatorType", stateOperatorTypes());
|
||||
allTypes.insert("RemovePolicyType", removePolicyTypes());
|
||||
allTypes.insert("StateType", stateTypeDescription());
|
||||
allTypes.insert("StateDescriptor", stateDescriptorDescription());
|
||||
allTypes.insert("StateEvaluator", stateEvaluatorDescription());
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public:
|
|||
DECLARE_TYPE(valueOperatorTypes, "ValueOperatorType")
|
||||
DECLARE_TYPE(createMethodTypes, "CreateMethodType")
|
||||
DECLARE_TYPE(setupMethodTypes, "SetupMethodType")
|
||||
DECLARE_TYPE(removePolicyTypes, "RemovePolicyType")
|
||||
DECLARE_OBJECT(paramType, "ParamType")
|
||||
DECLARE_OBJECT(param, "Param")
|
||||
DECLARE_OBJECT(paramDescriptor, "ParamDescriptor")
|
||||
|
|
|
|||
|
|
@ -32,11 +32,16 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||
params.clear(); returns.clear();
|
||||
setDescription("GetRules", "Get all configured rules");
|
||||
setParams("GetRules", params);
|
||||
QVariantList rules;
|
||||
rules.append(JsonTypes::ruleRef());
|
||||
returns.insert("rules", rules);
|
||||
returns.insert("ruleIds", QVariantList() << "uuid");
|
||||
setReturns("GetRules", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("GetRuleDetails", "Get details for the rule identified by ruleId");
|
||||
params.insert("ruleId", "uuid");
|
||||
setParams("GetRuleDetails", params);
|
||||
returns.insert("rule", JsonTypes::ruleRef());
|
||||
setReturns("GetRuleDetails", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("AddRule", "Add a rule.");
|
||||
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
||||
|
|
@ -58,6 +63,13 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||
returns.insert("success", "bool");
|
||||
returns.insert("errorMessage", "string");
|
||||
setReturns("RemoveRule", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("FindRules", "Find a list of rules containing any of the given parameters.");
|
||||
params.insert("deviceId", "uuid");
|
||||
setParams("FindRules", params);
|
||||
returns.insert("ruleIds", QVariantList() << "uuid");
|
||||
setReturns("FindRules", returns);
|
||||
}
|
||||
|
||||
QString RulesHandler::name() const
|
||||
|
|
@ -70,16 +82,26 @@ JsonReply* RulesHandler::GetRules(const QVariantMap ¶ms)
|
|||
Q_UNUSED(params)
|
||||
|
||||
QVariantList rulesList;
|
||||
foreach (const Rule &rule, GuhCore::instance()->rules()) {
|
||||
QVariantMap ruleMap = JsonTypes::packRule(rule);
|
||||
rulesList.append(ruleMap);
|
||||
foreach (const RuleId &ruleId, GuhCore::instance()->ruleIds()) {
|
||||
rulesList.append(ruleId);
|
||||
}
|
||||
QVariantMap returns;
|
||||
returns.insert("rules", rulesList);
|
||||
returns.insert("ruleIds", rulesList);
|
||||
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *RulesHandler::GetRuleDetails(const QVariantMap ¶ms)
|
||||
{
|
||||
RuleId ruleId = RuleId(params.value("ruleId").toString());
|
||||
Rule rule = GuhCore::instance()->findRule(ruleId);
|
||||
QVariantMap ruleData;
|
||||
if (!rule.id().isNull()) {
|
||||
ruleData.insert("rule", JsonTypes::packRule(rule));
|
||||
}
|
||||
return createReply(ruleData);
|
||||
}
|
||||
|
||||
JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||
{
|
||||
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
|
||||
|
|
@ -157,3 +179,18 @@ JsonReply* RulesHandler::RemoveRule(const QVariantMap ¶ms)
|
|||
}
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *RulesHandler::FindRules(const QVariantMap ¶ms)
|
||||
{
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QList<RuleId> rules = GuhCore::instance()->findRules(deviceId);
|
||||
|
||||
QVariantList rulesList;
|
||||
foreach (const RuleId &ruleId, rules) {
|
||||
rulesList.append(ruleId);
|
||||
}
|
||||
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleIds", rulesList);
|
||||
return createReply(returns);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ public:
|
|||
QString name() const override;
|
||||
|
||||
Q_INVOKABLE JsonReply* GetRules(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* GetRuleDetails(const QVariantMap ¶ms);
|
||||
|
||||
Q_INVOKABLE JsonReply* AddRule(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* FindRules(const QVariantMap ¶ms);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ RuleEngine::RuleEngine(QObject *parent) :
|
|||
settings.endGroup();
|
||||
|
||||
Rule rule = Rule(RuleId(idString), eventDescriptorList, stateEvaluator, actions);
|
||||
m_rules.append(rule);
|
||||
appendRule(rule);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -149,12 +149,12 @@ QList<Action> RuleEngine::evaluateEvent(const Event &event)
|
|||
qDebug() << "got event:" << event << device->name();
|
||||
|
||||
QList<Action> actions;
|
||||
for (int i = 0; i < m_rules.count(); ++i) {
|
||||
qDebug() << "evaluating rule" << i << m_rules.at(i).eventDescriptors();
|
||||
if (containsEvent(m_rules.at(i), event)) {
|
||||
if (m_rules.at(i).stateEvaluator().evaluate()) {
|
||||
foreach (const RuleId &id, m_ruleIds) {
|
||||
Rule rule = m_rules.value(id);
|
||||
if (containsEvent(rule, event)) {
|
||||
if (rule.stateEvaluator().evaluate()) {
|
||||
qDebug() << "states matching!";
|
||||
actions.append(m_rules.at(i).actions());
|
||||
actions.append(rule.actions());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<Even
|
|||
}
|
||||
|
||||
Rule rule = Rule(ruleId, eventDescriptorList, stateEvaluator, actions);
|
||||
m_rules.append(rule);
|
||||
appendRule(rule);
|
||||
emit ruleAdded(rule.id());
|
||||
|
||||
QSettings settings(m_settingsFile);
|
||||
|
|
@ -263,10 +263,18 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<Even
|
|||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
/*! Returns a list of all \l{Rule}{Rules} loaded in this Engine.*/
|
||||
/*! Returns a list of all \l{Rule}{Rules} loaded in this Engine.
|
||||
Be aware that this does not necessarily reflect the order of the rules in the engine.
|
||||
Use ruleIds() if you need the correct order.
|
||||
*/
|
||||
QList<Rule> RuleEngine::rules() const
|
||||
{
|
||||
return m_rules;
|
||||
return m_rules.values();
|
||||
}
|
||||
|
||||
QList<RuleId> RuleEngine::ruleIds() const
|
||||
{
|
||||
return m_ruleIds;
|
||||
}
|
||||
|
||||
/*! Removes the \l{Rule} with the given \a ruleId from the Engine.
|
||||
|
|
@ -274,22 +282,22 @@ QList<Rule> RuleEngine::rules() const
|
|||
was successful or not. */
|
||||
RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
||||
{
|
||||
for (int i = 0; i < m_rules.count(); ++i) {
|
||||
Rule rule = m_rules.at(i);
|
||||
if (rule.id() == ruleId) {
|
||||
int index = m_ruleIds.indexOf(ruleId);
|
||||
|
||||
m_rules.takeAt(i);
|
||||
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(rule.id().toString());
|
||||
settings.remove("");
|
||||
settings.endGroup();
|
||||
|
||||
emit ruleRemoved(rule.id());
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
if (index < 0) {
|
||||
return RuleErrorRuleNotFound;
|
||||
}
|
||||
return RuleErrorRuleNotFound;
|
||||
|
||||
m_ruleIds.takeAt(index);
|
||||
m_rules.remove(ruleId);
|
||||
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(ruleId.toString());
|
||||
settings.remove("");
|
||||
settings.endGroup();
|
||||
|
||||
emit ruleRemoved(ruleId);
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
Rule RuleEngine::findRule(const RuleId &ruleId)
|
||||
|
|
@ -302,6 +310,68 @@ Rule RuleEngine::findRule(const RuleId &ruleId)
|
|||
return Rule();
|
||||
}
|
||||
|
||||
QList<RuleId> RuleEngine::findRules(const DeviceId &deviceId)
|
||||
{
|
||||
// Find all offending rules
|
||||
QList<RuleId> offendingRules;
|
||||
foreach (const Rule &rule, m_rules) {
|
||||
bool offending = false;
|
||||
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
||||
if (eventDescriptor.deviceId() == deviceId) {
|
||||
offending = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!offending && rule.stateEvaluator().containsDevice(deviceId)) {
|
||||
offending = true;
|
||||
}
|
||||
if (!offending) {
|
||||
foreach (const Action &action, rule.actions()) {
|
||||
if (action.deviceId() == deviceId) {
|
||||
offending = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (offending) {
|
||||
offendingRules.append(rule.id());
|
||||
}
|
||||
}
|
||||
return offendingRules;
|
||||
}
|
||||
|
||||
void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId)
|
||||
{
|
||||
if (!m_rules.contains(id)) {
|
||||
return;
|
||||
}
|
||||
Rule rule = m_rules.value(id);
|
||||
QList<EventDescriptor> eventDescriptors = rule.eventDescriptors();
|
||||
QList<int> removeIndexes;
|
||||
for (int i = 0; i < eventDescriptors.count(); i++) {
|
||||
if (eventDescriptors.at(i).deviceId() == deviceId) {
|
||||
removeIndexes.append(i);
|
||||
}
|
||||
}
|
||||
while (removeIndexes.count() > 0) {
|
||||
eventDescriptors.takeAt(removeIndexes.takeLast());
|
||||
}
|
||||
StateEvaluator stateEvalatuator = rule.stateEvaluator();
|
||||
stateEvalatuator.removeDevice(deviceId);
|
||||
|
||||
QList<Action> actions = rule.actions();
|
||||
for (int i = 0; i < actions.count(); i++) {
|
||||
if (actions.at(i).deviceId() == deviceId) {
|
||||
removeIndexes.append(i);
|
||||
}
|
||||
}
|
||||
while (removeIndexes.count() > 0) {
|
||||
actions.takeAt(removeIndexes.takeLast());
|
||||
}
|
||||
Rule newRule(id, eventDescriptors, stateEvalatuator, actions);
|
||||
m_rules[id] = newRule;
|
||||
}
|
||||
|
||||
bool RuleEngine::containsEvent(const Rule &rule, const Event &event)
|
||||
{
|
||||
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
||||
|
|
@ -311,3 +381,9 @@ bool RuleEngine::containsEvent(const Rule &rule, const Event &event)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RuleEngine::appendRule(const Rule &rule)
|
||||
{
|
||||
m_rules.insert(rule.id(), rule);
|
||||
m_ruleIds.append(rule.id());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ public:
|
|||
RuleErrorActionTypeNotFound
|
||||
};
|
||||
|
||||
enum RemovePolicy {
|
||||
RemovePolicyCascade,
|
||||
RemovePolicyUpdate
|
||||
};
|
||||
|
||||
explicit RuleEngine(QObject *parent = 0);
|
||||
|
||||
QList<Action> evaluateEvent(const Event &event);
|
||||
|
|
@ -47,10 +52,14 @@ public:
|
|||
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions);
|
||||
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions);
|
||||
QList<Rule> rules() const;
|
||||
QList<RuleId> ruleIds() const;
|
||||
|
||||
RuleError removeRule(const RuleId &ruleId);
|
||||
|
||||
Rule findRule(const RuleId &ruleId);
|
||||
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||
|
||||
void removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId);
|
||||
|
||||
signals:
|
||||
void ruleAdded(const RuleId &ruleId);
|
||||
|
|
@ -59,10 +68,12 @@ signals:
|
|||
private:
|
||||
bool containsEvent(const Rule &rule, const Event &event);
|
||||
|
||||
void appendRule(const Rule &rule);
|
||||
|
||||
private:
|
||||
QString m_settingsFile;
|
||||
QList<Rule> m_rules;
|
||||
|
||||
QList<RuleId> m_ruleIds; // Keeping a list of RuleIds to keep sorting order...
|
||||
QHash<RuleId, Rule> m_rules; // ...but use a Hash for faster finding
|
||||
};
|
||||
|
||||
#endif // RULEENGINE_H
|
||||
|
|
|
|||
|
|
@ -99,6 +99,29 @@ bool StateEvaluator::evaluate() const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
||||
{
|
||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||
return true;
|
||||
}
|
||||
foreach (const StateEvaluator &childEvaluator, m_childEvaluators) {
|
||||
if (childEvaluator.containsDevice(deviceId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void StateEvaluator::removeDevice(const DeviceId &deviceId)
|
||||
{
|
||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||
m_stateDescriptor = StateDescriptor();
|
||||
}
|
||||
for (int i = 0; i < m_childEvaluators.count(); i++) {
|
||||
m_childEvaluators[i].removeDevice(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
void StateEvaluator::dumpToSettings(QSettings &settings, const QString &groupName) const
|
||||
{
|
||||
settings.beginGroup(groupName);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ public:
|
|||
void setOperatorType(StateOperator operatorType);
|
||||
|
||||
bool evaluate() const;
|
||||
bool containsDevice(const DeviceId &deviceId) const;
|
||||
|
||||
void removeDevice(const DeviceId &deviceId);
|
||||
|
||||
void dumpToSettings(QSettings &settings, const QString &groupName) const;
|
||||
static StateEvaluator loadFromSettings(QSettings &settings, const QString &groupPrefix);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
2
|
||||
3
|
||||
{
|
||||
"methods": {
|
||||
"Actions.ExecuteAction": {
|
||||
|
|
@ -194,7 +194,13 @@
|
|||
"Devices.RemoveConfiguredDevice": {
|
||||
"description": "Remove a device from the system.",
|
||||
"params": {
|
||||
"deviceId": "uuid"
|
||||
"deviceId": "uuid",
|
||||
"o:removePolicyList": [
|
||||
{
|
||||
"policy": "$ref:RemovePolicyType",
|
||||
"ruleId": "uuid"
|
||||
}
|
||||
]
|
||||
},
|
||||
"returns": {
|
||||
"errorMessage": "string",
|
||||
|
|
@ -261,13 +267,33 @@
|
|||
"success": "bool"
|
||||
}
|
||||
},
|
||||
"Rules.FindRules": {
|
||||
"description": "Find a list of rules containing any of the given parameters.",
|
||||
"params": {
|
||||
"deviceId": "uuid"
|
||||
},
|
||||
"returns": {
|
||||
"ruleIds": [
|
||||
"uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Rules.GetRuleDetails": {
|
||||
"description": "Get details for the rule identified by ruleId",
|
||||
"params": {
|
||||
"ruleId": "uuid"
|
||||
},
|
||||
"returns": {
|
||||
"rule": "$ref:Rule"
|
||||
}
|
||||
},
|
||||
"Rules.GetRules": {
|
||||
"description": "Get all configured rules",
|
||||
"params": {
|
||||
},
|
||||
"returns": {
|
||||
"rules": [
|
||||
"$ref:Rule"
|
||||
"ruleIds": [
|
||||
"uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -405,6 +431,10 @@
|
|||
"$ref:Param"
|
||||
]
|
||||
},
|
||||
"RemovePolicyType": [
|
||||
"RemovePolicyCascade",
|
||||
"RemovePolicyUpdate"
|
||||
],
|
||||
"Rule": {
|
||||
"actions": [
|
||||
"$ref:Action"
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ void TestRules::addRemoveRules()
|
|||
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
||||
|
||||
response = injectAndWait("Rules.GetRules");
|
||||
QVariantList rules = response.toMap().value("params").toMap().value("rules").toList();
|
||||
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
|
||||
|
||||
if (!success) {
|
||||
QVERIFY2(rules.count() == 0, "There should be no rules.");
|
||||
|
|
@ -150,10 +150,16 @@ void TestRules::addRemoveRules()
|
|||
}
|
||||
|
||||
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
||||
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
|
||||
QCOMPARE(RuleId(rules.first().toString()), newRuleId);
|
||||
|
||||
params.clear();
|
||||
params.insert("ruleId", newRuleId);
|
||||
response = injectAndWait("Rules.GetRuleDetails", params);
|
||||
// verifySuccess(response);
|
||||
|
||||
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
|
||||
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
||||
|
||||
QVariantList eventDescriptors = rule.value("eventDescriptors").toList();
|
||||
if (!eventDescriptor.isEmpty()) {
|
||||
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
|
||||
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor, "Event descriptor doesn't match");
|
||||
|
|
@ -172,7 +178,7 @@ void TestRules::addRemoveRules()
|
|||
}
|
||||
}
|
||||
|
||||
QVariantList replyActions = rules.first().toMap().value("actions").toList();
|
||||
QVariantList replyActions = rule.value("actions").toList();
|
||||
QVERIFY2(actions == replyActions, "Actions don't match");
|
||||
|
||||
|
||||
|
|
@ -251,12 +257,18 @@ void TestRules::loadStoreConfig()
|
|||
|
||||
response = injectAndWait("Rules.GetRules");
|
||||
|
||||
QVariantList rules = response.toMap().value("params").toMap().value("rules").toList();
|
||||
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
|
||||
|
||||
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
||||
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
|
||||
QCOMPARE(RuleId(rules.first().toString()), newRuleId);
|
||||
|
||||
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
|
||||
params.clear();
|
||||
params.insert("ruleId", rules.first().toString());
|
||||
response = injectAndWait("Rules.GetRuleDetails", params);
|
||||
|
||||
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
||||
|
||||
QVariantList eventDescriptors = rule.value("eventDescriptors").toList();
|
||||
QVERIFY2(eventDescriptors.count() == 2, "There shoud be exactly 2 eventDescriptors");
|
||||
foreach (const QVariant &expectedEventDescriptorVariant, eventDescriptorList) {
|
||||
bool found = false;
|
||||
|
|
@ -270,7 +282,7 @@ void TestRules::loadStoreConfig()
|
|||
QVERIFY2(found, "missing eventdescriptor");
|
||||
}
|
||||
|
||||
QVariantList replyActions = rules.first().toMap().value("actions").toList();
|
||||
QVariantList replyActions = rule.value("actions").toList();
|
||||
foreach (const QVariant &actionVariant, actions) {
|
||||
bool found = false;
|
||||
foreach (const QVariant &replyActionVariant, replyActions) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue