use of org.openhab.core.automation.internal.ruleengine.WrappedCondition 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;
}
use of org.openhab.core.automation.internal.ruleengine.WrappedCondition in project openhab-core by openhab.
the class RuleEngineImpl method calculateConditions.
/**
* This method checks if all rule's condition are satisfied or not.
*
* @param rule the checked rule
* @return true when all conditions of the rule are satisfied, false otherwise.
*/
private boolean calculateConditions(WrappedRule rule) {
List<WrappedCondition> conditions = rule.getConditions();
if (conditions.isEmpty()) {
return true;
}
final String ruleUID = rule.getUID();
RuleStatus ruleStatus = null;
for (WrappedCondition wrappedCondition : conditions) {
ruleStatus = getRuleStatus(ruleUID);
if (ruleStatus != RuleStatus.RUNNING) {
return false;
}
final Condition condition = wrappedCondition.unwrap();
ConditionHandler tHandler = wrappedCondition.getModuleHandler();
Map<String, Object> context = getContext(ruleUID, wrappedCondition.getConnections());
if (tHandler != null && !tHandler.isSatisfied(Collections.unmodifiableMap(context))) {
logger.debug("The condition '{}' of rule '{}' is unsatisfied.", condition.getId(), ruleUID);
return false;
}
}
return true;
}
use of org.openhab.core.automation.internal.ruleengine.WrappedCondition 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);
}
}
}
}
}
use of org.openhab.core.automation.internal.ruleengine.WrappedCondition 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);
}
}
}
}
Aggregations