/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 . * * 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 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()), m_actions(QList()), m_exitActions(QList()), 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()) { qCWarning(dcRuleEngine) << "Rule not consistent. The exitActions will never be executed if the rule contains an eventDescriptor but no stateEvaluator or calendarItem."; 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()) { qCWarning(dcRuleEngine) << "Rule not consistent. The exitActions will never be executed if the rule contains a timeEvent but no stateEvaluator or calendarItem."; return false; } // check if there are any actions if (actions().isEmpty()) { qCWarning(dcRuleEngine) << "Rule not consistent. A rule without actions has no effect."; 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) { 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.space(); } Rules::Rules() { } Rules::Rules(const QList &other): QList(other) { } QVariant Rules::get(int index) const { return QVariant::fromValue(at(index)); } void Rules::put(const QVariant &variant) { append(variant.value()); } }