Search in sources :

Example 1 with WrappedAction

use of org.openhab.core.automation.internal.ruleengine.WrappedAction in project openhab-core by openhab.

the class RuleEngineImpl method setModuleHandlers.

/**
 * This method links modules to corresponding module handlers.
 *
 * @param rUID id of rule containing these modules
 * @param modules list of modules
 * @return null when all modules are connected or list of RuleErrors for missing handlers.
 */
@Nullable
private <T extends WrappedModule<?, ?>> String setModuleHandlers(String rUID, List<T> modules) {
    StringBuilder sb = null;
    for (T mm : modules) {
        final Module m = mm.unwrap();
        try {
            ModuleHandler moduleHandler = getModuleHandler(m, rUID);
            if (moduleHandler != null) {
                if (mm instanceof WrappedAction) {
                    ((WrappedAction) mm).setModuleHandler((ActionHandler) moduleHandler);
                } else if (mm instanceof WrappedCondition) {
                    ((WrappedCondition) mm).setModuleHandler((ConditionHandler) moduleHandler);
                } else if (mm instanceof WrappedTrigger) {
                    ((WrappedTrigger) mm).setModuleHandler((TriggerHandler) moduleHandler);
                }
            } else {
                if (sb == null) {
                    sb = new StringBuilder();
                }
                String message = "Missing handler '" + m.getTypeUID() + "' for module '" + m.getId() + "'";
                sb.append(message).append("\n");
                logger.trace(message);
            }
        } catch (Throwable t) {
            if (sb == null) {
                sb = new StringBuilder();
            }
            String message = "Getting handler '" + m.getTypeUID() + "' for module '" + m.getId() + "' failed: " + t.getMessage();
            sb.append(message).append("\n");
            logger.trace(message);
        }
    }
    return sb != null ? sb.toString() : null;
}
Also used : ModuleHandler(org.openhab.core.automation.handler.ModuleHandler) WrappedCondition(org.openhab.core.automation.internal.ruleengine.WrappedCondition) ConditionHandler(org.openhab.core.automation.handler.ConditionHandler) WrappedTrigger(org.openhab.core.automation.internal.ruleengine.WrappedTrigger) Module(org.openhab.core.automation.Module) WrappedModule(org.openhab.core.automation.internal.ruleengine.WrappedModule) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 2 with WrappedAction

use of org.openhab.core.automation.internal.ruleengine.WrappedAction in project openhab-core by openhab.

the class RuleEngineImpl method autoMapConnections.

/**
 * The auto mapping tries to link not connected module inputs to output of other modules. The auto mapping will link
 * input to output only when following criteria are done: 1) input must not be connected. The auto mapping will not
 * overwrite explicit connections done by the user. 2) input tags must be subset of the output tags. 3) condition
 * inputs can be connected only to triggers' outputs 4) action outputs can be connected to both conditions and
 * actions
 * outputs 5) There is only one output, based on previous criteria, where the input can connect to. If more then one
 * candidate outputs exists for connection, this is a conflict and the auto mapping leaves the input unconnected.
 * Auto mapping is always applied when the rule is added or updated. It changes initial value of inputs of
 * conditions and actions participating in the rule. If an "auto map" connection has to be removed, the tags of
 * corresponding input/output have to be changed.
 *
 * @param rule updated rule
 */
private void autoMapConnections(WrappedRule rule) {
    Map<Set<String>, OutputRef> triggerOutputTags = new HashMap<>(11);
    for (WrappedTrigger mt : rule.getTriggers()) {
        final Trigger t = mt.unwrap();
        TriggerType tt = (TriggerType) mtRegistry.get(t.getTypeUID());
        if (tt != null) {
            initTagsMap(t.getId(), tt.getOutputs(), triggerOutputTags);
        }
    }
    Map<Set<String>, OutputRef> actionOutputTags = new HashMap<>(11);
    for (WrappedAction ma : rule.getActions()) {
        final Action a = ma.unwrap();
        ActionType at = (ActionType) mtRegistry.get(a.getTypeUID());
        if (at != null) {
            initTagsMap(a.getId(), at.getOutputs(), actionOutputTags);
        }
    }
    // auto mapping of conditions
    if (!triggerOutputTags.isEmpty()) {
        for (WrappedCondition mc : rule.getConditions()) {
            final Condition c = mc.unwrap();
            boolean isConnectionChanged = false;
            ConditionType ct = (ConditionType) mtRegistry.get(c.getTypeUID());
            if (ct != null) {
                Set<Connection> connections = copyConnections(mc.getConnections());
                for (Input input : ct.getInputs()) {
                    if (isConnected(input, connections)) {
                        // the input is already connected. Skip it.
                        continue;
                    }
                    if (addAutoMapConnections(input, triggerOutputTags, connections)) {
                        isConnectionChanged = true;
                    }
                }
                if (isConnectionChanged) {
                    // update condition inputs
                    Map<String, String> connectionMap = getConnectionMap(connections);
                    mc.setInputs(connectionMap);
                    mc.setConnections(connections);
                }
            }
        }
    }
    // auto mapping of actions
    if (!triggerOutputTags.isEmpty() || !actionOutputTags.isEmpty()) {
        for (final WrappedAction ma : rule.getActions()) {
            final Action a = ma.unwrap();
            boolean isConnectionChanged = false;
            ActionType at = (ActionType) mtRegistry.get(a.getTypeUID());
            if (at != null) {
                Set<Connection> connections = copyConnections(ma.getConnections());
                for (Input input : at.getInputs()) {
                    if (isConnected(input, connections)) {
                        // the input is already connected. Skip it.
                        continue;
                    }
                    if (addAutoMapConnections(input, triggerOutputTags, connections)) {
                        isConnectionChanged = true;
                    }
                    if (addAutoMapConnections(input, actionOutputTags, connections)) {
                        isConnectionChanged = true;
                    }
                }
                if (isConnectionChanged) {
                    // update condition inputs
                    Map<String, String> connectionMap = getConnectionMap(connections);
                    ma.setInputs(connectionMap);
                    ma.setConnections(connections);
                }
            }
        }
    }
}
Also used : WrappedCondition(org.openhab.core.automation.internal.ruleengine.WrappedCondition) Condition(org.openhab.core.automation.Condition) CompositeTriggerType(org.openhab.core.automation.type.CompositeTriggerType) TriggerType(org.openhab.core.automation.type.TriggerType) Action(org.openhab.core.automation.Action) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction) Set(java.util.Set) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) HashSet(java.util.HashSet) CompositeActionType(org.openhab.core.automation.type.CompositeActionType) ActionType(org.openhab.core.automation.type.ActionType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) WrappedTrigger(org.openhab.core.automation.internal.ruleengine.WrappedTrigger) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction) Input(org.openhab.core.automation.type.Input) WrappedTrigger(org.openhab.core.automation.internal.ruleengine.WrappedTrigger) Trigger(org.openhab.core.automation.Trigger) WrappedCondition(org.openhab.core.automation.internal.ruleengine.WrappedCondition) CompositeConditionType(org.openhab.core.automation.type.CompositeConditionType) ConditionType(org.openhab.core.automation.type.ConditionType)

Example 3 with WrappedAction

use of org.openhab.core.automation.internal.ruleengine.WrappedAction in project openhab-core by openhab.

the class RuleEngineImpl method setRule.

/**
 * This method tries to initialize the rule. It uses available {@link ModuleHandlerFactory}s to create
 * {@link ModuleHandler}s for all {@link ModuleImpl}s of the {@link Rule} and to link them. When all the modules
 * have associated module handlers then the {@link Rule} is initialized and it is ready to working. It goes into
 * idle state. Otherwise the Rule stays into not initialized and continue to wait missing handlers, module types
 * or templates.
 *
 * @param rule the rule which tried to be initialized.
 */
private void setRule(WrappedRule rule) {
    if (isDisposed) {
        return;
    }
    String rUID = rule.getUID();
    setStatus(rUID, new RuleStatusInfo(RuleStatus.INITIALIZING));
    try {
        for (final WrappedAction action : rule.getActions()) {
            updateMapModuleTypeToRule(rUID, action.unwrap().getTypeUID());
            action.setConnections(ConnectionValidator.getConnections(action.getInputs()));
        }
        for (final WrappedCondition condition : rule.getConditions()) {
            updateMapModuleTypeToRule(rUID, condition.unwrap().getTypeUID());
            condition.setConnections(ConnectionValidator.getConnections(condition.getInputs()));
        }
        for (final WrappedTrigger trigger : rule.getTriggers()) {
            updateMapModuleTypeToRule(rUID, trigger.unwrap().getTypeUID());
        }
        validateModuleIDs(rule);
        autoMapConnections(rule);
        ConnectionValidator.validateConnections(mtRegistry, rule.unwrap());
    } catch (IllegalArgumentException e) {
        // change status to UNINITIALIZED
        setStatus(rUID, new RuleStatusInfo(RuleStatus.UNINITIALIZED, RuleStatusDetail.INVALID_RULE, "Validation of rule " + rUID + " has failed! " + e.getLocalizedMessage()));
        return;
    }
    final boolean activated = activateRule(rule);
    if (activated) {
        Future<?> f = scheduleTasks.remove(rUID);
        if (f != null) {
            if (!f.isDone()) {
                f.cancel(true);
            }
        }
    }
}
Also used : RuleStatusInfo(org.openhab.core.automation.RuleStatusInfo) WrappedCondition(org.openhab.core.automation.internal.ruleengine.WrappedCondition) WrappedTrigger(org.openhab.core.automation.internal.ruleengine.WrappedTrigger) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction)

Example 4 with WrappedAction

use of org.openhab.core.automation.internal.ruleengine.WrappedAction in project openhab-core by openhab.

the class RuleEngineImpl method executeActions.

/**
 * This method evaluates actions of the {@link Rule} and set their {@link Output}s when they exists.
 *
 * @param rule executed rule.
 */
private void executeActions(WrappedRule rule, boolean stopOnFirstFail) {
    final String ruleUID = rule.getUID();
    final Collection<WrappedAction> actions = rule.getActions();
    if (actions.isEmpty()) {
        return;
    }
    RuleStatus ruleStatus = null;
    for (WrappedAction wrappedAction : actions) {
        ruleStatus = getRuleStatus(ruleUID);
        if (ruleStatus != RuleStatus.RUNNING) {
            return;
        }
        final Action action = wrappedAction.unwrap();
        ActionHandler aHandler = wrappedAction.getModuleHandler();
        if (aHandler != null) {
            Map<String, Object> context = getContext(ruleUID, wrappedAction.getConnections());
            try {
                Map<String, ?> outputs = aHandler.execute(Collections.unmodifiableMap(context));
                if (outputs != null) {
                    context = getContext(ruleUID, null);
                    updateContext(ruleUID, action.getId(), outputs);
                }
            } catch (Throwable t) {
                String errMessage = "Fail to execute action: " + action.getId();
                if (stopOnFirstFail) {
                    RuntimeException re = new RuntimeException(errMessage, t);
                    throw re;
                } else {
                    logger.warn(errMessage, t);
                }
            }
        }
    }
}
Also used : Action(org.openhab.core.automation.Action) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction) RuleStatus(org.openhab.core.automation.RuleStatus) WrappedAction(org.openhab.core.automation.internal.ruleengine.WrappedAction) ActionHandler(org.openhab.core.automation.handler.ActionHandler)

Aggregations

WrappedAction (org.openhab.core.automation.internal.ruleengine.WrappedAction)4 WrappedCondition (org.openhab.core.automation.internal.ruleengine.WrappedCondition)3 WrappedTrigger (org.openhab.core.automation.internal.ruleengine.WrappedTrigger)3 Action (org.openhab.core.automation.Action)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CopyOnWriteArraySet (java.util.concurrent.CopyOnWriteArraySet)1 Nullable (org.eclipse.jdt.annotation.Nullable)1 Condition (org.openhab.core.automation.Condition)1 Module (org.openhab.core.automation.Module)1 RuleStatus (org.openhab.core.automation.RuleStatus)1 RuleStatusInfo (org.openhab.core.automation.RuleStatusInfo)1 Trigger (org.openhab.core.automation.Trigger)1 ActionHandler (org.openhab.core.automation.handler.ActionHandler)1 ConditionHandler (org.openhab.core.automation.handler.ConditionHandler)1 ModuleHandler (org.openhab.core.automation.handler.ModuleHandler)1 WrappedModule (org.openhab.core.automation.internal.ruleengine.WrappedModule)1 ActionType (org.openhab.core.automation.type.ActionType)1