This moves all the things and rules logic away from NymeaCore into their respective modules where it belongs. One major change is the removal of the removePolicy functionality. This was somewhat broken as it was only working for rules but not for all the other modules like scripts, experiences etc. After an attempt to create something that works with all modules it really seemed that this does not make a lot of sence after all, given that updating rules would in most cases leave something very broken behind and removing them was the only sane thing to do. On the other hand, experience plugins may not work well with such a policy eithre as they may require to do their own special thing. So in the end the removePolicy was dropped altogether. Apps should instead figure out themselves what removal of a thing may imply and inform the user about that beforehand.
281 lines
7.3 KiB
C++
281 lines
7.3 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright 2013 - 2020, 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
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*!
|
|
\class nymeaserver::Rule
|
|
\brief This class represents a rule.
|
|
|
|
\ingroup rules
|
|
\inmodule core
|
|
|
|
A Rule is always triggered by an \l{EventDescriptor}, has \l{State}{States}
|
|
to be compared and \l{RuleAction}{RuleActions} to be executed.
|
|
|
|
\sa EventDescriptor, State, RuleAction
|
|
*/
|
|
|
|
|
|
#include "rule.h"
|
|
#include "loggingcategories.h"
|
|
|
|
#include <QDebug>
|
|
|
|
namespace nymeaserver {
|
|
|
|
/*! Constructs an empty, invalid \l{Rule}. */
|
|
Rule::Rule():
|
|
m_id(RuleId()),
|
|
m_name(QString()),
|
|
m_timeDescriptor(TimeDescriptor()),
|
|
m_stateEvaluator(StateEvaluator()),
|
|
m_eventDescriptors(QList<EventDescriptor>()),
|
|
m_actions(QList<RuleAction>()),
|
|
m_exitActions(QList<RuleAction>()),
|
|
m_enabled(true),
|
|
m_active(false),
|
|
m_statesActive(false),
|
|
m_timeActive(false),
|
|
m_executable(false)
|
|
{
|
|
|
|
}
|
|
|
|
/*! Returns the id of this \l{Rule}. */
|
|
RuleId Rule::id() const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
/*! Sets the \a ruleId of this \l{Rule}. */
|
|
void Rule::setId(const RuleId &ruleId)
|
|
{
|
|
m_id = ruleId;
|
|
}
|
|
|
|
/*! Returns the name of this rule. */
|
|
QString Rule::name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*! Sets the \a name of this \l{Rule}. */
|
|
void Rule::setName(const QString &name)
|
|
{
|
|
m_name = name;
|
|
}
|
|
|
|
/*! Returns true if the rule is active. */
|
|
bool Rule::active() const
|
|
{
|
|
return m_active;
|
|
}
|
|
|
|
/*! Returns true if the rule is active regarding the StateEvaluator evaluation. */
|
|
bool Rule::statesActive() const
|
|
{
|
|
return m_statesActive;
|
|
}
|
|
|
|
/*! Returns true if the rule is active regarding the TimeDescriptor evaluation. */
|
|
bool Rule::timeActive() const
|
|
{
|
|
if (m_timeDescriptor.calendarItems().isEmpty())
|
|
return true;
|
|
|
|
return m_timeActive;
|
|
}
|
|
|
|
/*! Returns the \l{TimeDescriptor} or this Rule. */
|
|
TimeDescriptor Rule::timeDescriptor() const
|
|
{
|
|
return m_timeDescriptor;
|
|
}
|
|
|
|
/*! Sets the \a timeDescriptor of this \l{Rule}. */
|
|
void Rule::setTimeDescriptor(const TimeDescriptor &timeDescriptor)
|
|
{
|
|
m_timeDescriptor = timeDescriptor;
|
|
}
|
|
|
|
/*! Returns the StateEvaluator that needs to evaluate successfully in order for this to Rule apply. */
|
|
StateEvaluator Rule::stateEvaluator() const
|
|
{
|
|
return m_stateEvaluator;
|
|
}
|
|
|
|
/*! Sets the \a stateEvaluator of this \l{Rule}. */
|
|
void Rule::setStateEvaluator(const StateEvaluator &stateEvaluator)
|
|
{
|
|
m_stateEvaluator = stateEvaluator;
|
|
}
|
|
|
|
/*! Returns the \l{EventDescriptor} for this Rule.*/
|
|
EventDescriptors Rule::eventDescriptors() const
|
|
{
|
|
return m_eventDescriptors;
|
|
}
|
|
|
|
/*! Sets the \a eventDescriptors of this \l{Rule}. */
|
|
void Rule::setEventDescriptors(const EventDescriptors &eventDescriptors)
|
|
{
|
|
m_eventDescriptors = eventDescriptors;
|
|
}
|
|
|
|
/*! Returns the \l{RuleAction}{RuleActions} to be executed when this Rule is matched and states match. */
|
|
RuleActions Rule::actions() const
|
|
{
|
|
return m_actions;
|
|
}
|
|
|
|
/*! Sets the \a actions of this \l{Rule}. */
|
|
void Rule::setActions(const RuleActions actions)
|
|
{
|
|
m_actions = actions;
|
|
}
|
|
|
|
/*! Returns the \l{RuleAction}{RuleActions} to be executed when this Rule leaves the active state. */
|
|
RuleActions Rule::exitActions() const
|
|
{
|
|
return m_exitActions;
|
|
}
|
|
|
|
/*! Sets the \a exitActions of this \l{Rule}. */
|
|
void Rule::setExitActions(const RuleActions exitActions)
|
|
{
|
|
m_exitActions = exitActions;
|
|
}
|
|
|
|
/*! Returns true if the rule is enabled. */
|
|
bool Rule::enabled() const {
|
|
return m_enabled;
|
|
}
|
|
|
|
/*! Set the \a enabled flag of this rule. In order to actually enable/disable the rule you still need to
|
|
* update the \l{RuleEngine} */
|
|
void Rule::setEnabled(const bool &enabled)
|
|
{
|
|
m_enabled = enabled;
|
|
}
|
|
|
|
/*! Returns true if the rule is executable. */
|
|
bool Rule::executable() const
|
|
{
|
|
return m_executable;
|
|
}
|
|
|
|
/*! Set the rule \a executable. */
|
|
void Rule::setExecutable(const bool &executable)
|
|
{
|
|
m_executable = executable;
|
|
}
|
|
|
|
/*! Returns true if this \l{Rule} is valid. A \l{Rule} with a valid \l{id()} is valid. */
|
|
bool Rule::isValid() const
|
|
{
|
|
return !m_id.isNull();
|
|
}
|
|
|
|
/*! Returns true if this \l{Rule} is consistent. */
|
|
bool Rule::isConsistent() const
|
|
{
|
|
// check if this rules is based on any event and contains exit actions
|
|
if (!eventDescriptors().isEmpty() && stateEvaluator().isEmpty() && timeDescriptor().calendarItems().isEmpty() && !exitActions().isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
// check if this rules is based on any time events and contains exit actions
|
|
if (!timeDescriptor().timeEventItems().isEmpty() && stateEvaluator().isEmpty() && timeDescriptor().calendarItems().isEmpty() && !exitActions().isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
// check if there are any actions
|
|
if (actions().isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Rule::setStatesActive(const bool &statesActive)
|
|
{
|
|
m_statesActive = statesActive;
|
|
}
|
|
|
|
void Rule::setTimeActive(const bool &timeActive)
|
|
{
|
|
m_timeActive = timeActive;
|
|
}
|
|
|
|
void Rule::setActive(const bool &active)
|
|
{
|
|
m_active = active;
|
|
}
|
|
|
|
/*! Print a Rule with all its contents to QDebug. Note that this might print a lot of data.
|
|
* It is useful to debug, but be cautionous with using this in production code. */
|
|
QDebug operator<<(QDebug dbg, const Rule &rule)
|
|
{
|
|
QDebugStateSaver saver(dbg);
|
|
dbg.nospace() << endl << "=== Rule begin ===" << endl;
|
|
dbg.nospace() << "ID:" << rule.id().toString() << endl;
|
|
dbg.nospace() << "Name:" << rule.name() << endl;
|
|
dbg.nospace() << "Enabled:" << rule.enabled() << endl;
|
|
dbg.nospace() << "Active:" << rule.active() << endl;
|
|
dbg.nospace() << rule.eventDescriptors();
|
|
dbg.nospace() << rule.timeDescriptor();
|
|
dbg.nospace() << rule.stateEvaluator();
|
|
dbg.nospace() << "Actions:" << rule.actions();
|
|
dbg.nospace() << "ExitActions:" << rule.exitActions();
|
|
dbg.nospace() << "=== Rule end ===";
|
|
return dbg;
|
|
}
|
|
|
|
Rules::Rules()
|
|
{
|
|
|
|
}
|
|
|
|
Rules::Rules(const QList<Rule> &other): QList<Rule>(other)
|
|
{
|
|
|
|
}
|
|
|
|
QVariant Rules::get(int index) const
|
|
{
|
|
return QVariant::fromValue(at(index));
|
|
}
|
|
|
|
void Rules::put(const QVariant &variant)
|
|
{
|
|
append(variant.value<Rule>());
|
|
}
|
|
|
|
}
|