use of org.eclipse.smarthome.automation.type.ConditionType in project smarthome by eclipse.
the class RuleEngine 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 r updated rule
*/
private void autoMapConnections(RuntimeRule r) {
Map<Set<String>, OutputRef> triggerOutputTags = new HashMap<Set<String>, OutputRef>(11);
for (Trigger t : r.getTriggers()) {
TriggerType tt = (TriggerType) mtRegistry.get(t.getTypeUID());
if (tt != null) {
initTagsMap(t.getId(), tt.getOutputs(), triggerOutputTags);
}
}
Map<Set<String>, OutputRef> actionOutputTags = new HashMap<Set<String>, OutputRef>(11);
for (Action a : r.getActions()) {
ActionType at = (ActionType) mtRegistry.get(a.getTypeUID());
if (at != null) {
initTagsMap(a.getId(), at.getOutputs(), actionOutputTags);
}
}
// auto mapping of conditions
if (!triggerOutputTags.isEmpty()) {
for (Condition c : r.getConditions()) {
boolean isConnectionChanged = false;
ConditionType ct = (ConditionType) mtRegistry.get(c.getTypeUID());
if (ct != null) {
Set<Connection> connections = ((RuntimeCondition) c).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
connections = ((RuntimeCondition) c).getConnections();
Map<String, String> connectionMap = getConnectionMap(connections);
c.setInputs(connectionMap);
}
}
}
}
// auto mapping of actions
if (!triggerOutputTags.isEmpty() || !actionOutputTags.isEmpty()) {
for (Action a : r.getActions()) {
boolean isConnectionChanged = false;
ActionType at = (ActionType) mtRegistry.get(a.getTypeUID());
if (at != null) {
Set<Connection> connections = ((RuntimeAction) a).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
connections = ((RuntimeAction) a).getConnections();
Map<String, String> connectionMap = getConnectionMap(connections);
a.setInputs(connectionMap);
}
}
}
}
}
use of org.eclipse.smarthome.automation.type.ConditionType in project smarthome by eclipse.
the class ModuleTypeRegistryImpl method createCopy.
private ModuleType createCopy(ModuleType mType) {
if (mType == null) {
return null;
}
ModuleType result;
if (mType instanceof CompositeTriggerType) {
CompositeTriggerType m = (CompositeTriggerType) mType;
result = new CompositeTriggerType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getOutputs(), copyTriggers(m.getChildren()));
} else if (mType instanceof TriggerType) {
TriggerType m = (TriggerType) mType;
result = new TriggerType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getOutputs());
} else if (mType instanceof CompositeConditionType) {
CompositeConditionType m = (CompositeConditionType) mType;
result = new CompositeConditionType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getInputs(), copyConditions(m.getChildren()));
} else if (mType instanceof ConditionType) {
ConditionType m = (ConditionType) mType;
result = new ConditionType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getInputs());
} else if (mType instanceof CompositeActionType) {
CompositeActionType m = (CompositeActionType) mType;
result = new CompositeActionType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getInputs(), m.getOutputs(), copyActions(m.getChildren()));
} else if (mType instanceof ActionType) {
ActionType m = (ActionType) mType;
result = new ActionType(mType.getUID(), mType.getConfigurationDescriptions(), mType.getLabel(), mType.getDescription(), mType.getTags(), mType.getVisibility(), m.getInputs(), m.getOutputs());
} else {
throw new IllegalArgumentException("Invalid template type:" + mType);
}
return result;
}
use of org.eclipse.smarthome.automation.type.ConditionType in project smarthome by eclipse.
the class ModuleTypeRegistryImpl method getConditions.
@Override
public Collection<ConditionType> getConditions(Locale locale, String... tags) {
Collection<ModuleType> moduleTypes = getByTags(locale, tags);
Collection<ConditionType> conditionTypes = new ArrayList<ConditionType>();
for (ModuleType mt : moduleTypes) {
if (mt instanceof ConditionType) {
conditionTypes.add((ConditionType) mt);
}
}
return conditionTypes;
}
use of org.eclipse.smarthome.automation.type.ConditionType in project smarthome by eclipse.
the class ModuleTypeRegistryImpl method getConditions.
@Override
public Collection<ConditionType> getConditions(String... tags) {
Collection<ModuleType> moduleTypes = getByTags(tags);
Collection<ConditionType> conditionTypes = new ArrayList<ConditionType>();
for (ModuleType mt : moduleTypes) {
if (mt instanceof ConditionType) {
conditionTypes.add((ConditionType) mt);
}
}
return conditionTypes;
}
use of org.eclipse.smarthome.automation.type.ConditionType in project smarthome by eclipse.
the class ConnectionValidator method validateConditionConnections.
/**
* The method validates connections between trigger's outputs and condition's inputs. It checks is there unconnected
* required inputs and compatibility of data types of connected inputs and outputs. Throws exception if they are
* incompatible.
*
* @param condition is a Condition module whose connections have to be validated
* @param triggers is a list with triggers of the rule on which the condition belongs
* @throws IllegalArgumentException when validation fails.
*/
private static void validateConditionConnections(RuntimeCondition condition, List<Trigger> triggers) {
// get module type of the condition
ConditionType type = (ConditionType) mtRegistry.get(condition.getTypeUID());
if (type == null) {
// if module type not exists in the system - throws exception
throw new IllegalArgumentException("Condition Type \"" + condition.getTypeUID() + "\" does not exist!");
}
// get inputs of the condition according to module type definition
List<Input> inputs = type.getInputs();
// gets connected inputs from the condition module and put them into map
Set<Connection> cons = condition.getConnections();
Map<String, Connection> connectionsMap = new HashMap<String, Connection>();
Iterator<Connection> connectionsI = cons.iterator();
while (connectionsI.hasNext()) {
Connection connection = connectionsI.next();
String inputName = connection.getInputName();
connectionsMap.put(inputName, connection);
}
// checks is there unconnected required inputs
if (inputs != null && !inputs.isEmpty()) {
for (Input input : inputs) {
String name = input.getName();
Connection connection = connectionsMap.get(name);
if (connection != null) {
checkConnection(connection, input, triggers);
} else if (input.isRequired()) {
throw new IllegalArgumentException("Required input \"" + name + "\" of the condition \"" + condition.getId() + "\" not connected");
}
}
}
}
Aggregations