/** * Copyright (c) 1997, 2015 by ProSyst Software GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.automation.sample.extension.java; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.smarthome.automation.Action; import org.eclipse.smarthome.automation.Condition; import org.eclipse.smarthome.automation.Rule; import org.eclipse.smarthome.automation.RuleProvider; import org.eclipse.smarthome.automation.Trigger; import org.eclipse.smarthome.automation.sample.extension.java.template.AirConditionerRuleTemplate; import org.eclipse.smarthome.automation.sample.extension.java.type.LightsTriggerType; import org.eclipse.smarthome.automation.sample.extension.java.type.StateConditionType; import org.eclipse.smarthome.automation.sample.extension.java.type.TemperatureConditionType; import org.eclipse.smarthome.automation.sample.extension.java.type.WelcomeHomeActionType; import org.eclipse.smarthome.config.core.ConfigDescriptionParameter; import org.eclipse.smarthome.config.core.ConfigDescriptionParameter.Type; import org.eclipse.smarthome.config.core.ConfigDescriptionParameterBuilder; import org.eclipse.smarthome.config.core.Configuration; import org.eclipse.smarthome.core.common.registry.ProviderChangeListener; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * This class presents simple implementation of {@link RuleProvider} interface. It provides four rules that give ability * to the user to switch on the air conditioner and lights, and to lower the blinds in its home remotely. * * @author Ana Dimova - Initial Contribution * */ public class WelcomeHomeRulesProvider implements RuleProvider { public static final String CONFIG_UNIT = "unit"; public static final String CONFIG_EXPECTED_RESULT = "expectedResult"; static final String AC_UID = "AirConditionerSwitchOnRule"; static final String L_UID = "LightsSwitchOnRule"; Map<String, Rule> rules; @SuppressWarnings("rawtypes") private ServiceRegistration providerReg; private Collection<ProviderChangeListener<Rule>> listeners; /** * This method is used to initialize the provided rules by using templates and from scratch. * The configuration of the rule created by template should contain as keys all required parameter names of the * configuration of the template and their values. * In this example the UIDs of the rules is given by the provider, but can be <code>null</code>. * Then the RuleEngine will generate the UID for each provided rule. */ public WelcomeHomeRulesProvider() { // initialize the "AirConditionerSwitchOnRule" rule from template by using UID, templateUID and configuration. Rule acSwitchOn = createACRule(); // initialize the "LightsSwitchOnRule" rule from scratch by using trigger, condition, action, configDescriptions // and configuration, tags. Rule lightsSwitchOn = createLightsRule(); rules = new HashMap<String, Rule>(); rules.put(AC_UID, acSwitchOn); rules.put(L_UID, lightsSwitchOn); } @Override public void addProviderChangeListener(ProviderChangeListener<Rule> listener) { if (listeners == null) { listeners = new ArrayList<ProviderChangeListener<Rule>>(); } listeners.add(listener); // keep all listeners, interested about changing the rules to can inform them if // there is change on some rules } @Override public Collection<Rule> getAll() { return rules.values(); // adding the provided rules into RuleEngine } @Override public void removeProviderChangeListener(ProviderChangeListener<Rule> listener) { if (listeners != null) { listeners.remove(listener); } } /** * This method is used to update the provided rules configuration. * * @param uid * specifies the rule for updating by UID * @param template * specifies the rule template by UID * @param config * gives the new configuration of the rule */ public void update(String uid, String template, Configuration config) { // specific for this application Rule oldelement = rules.get(uid); Rule element = new Rule(uid); element.setTemplateUID(template); element.setConfiguration(config); rules.put(uid, element); // inform all listeners, interested about changing of the rules for (ProviderChangeListener<Rule> listener : listeners) { listener.updated(this, oldelement, element); } } /** * This method is used for registration of the WelcomeHomeRulesProvider as a {@link RuleProvider} service. * * @param bc * is a bundle's execution context within the Framework. */ public void register(BundleContext bc) { providerReg = bc.registerService(RuleProvider.class.getName(), this, null); } /** * This method is used to unregister the WelcomeHomeRulesProvider service. */ public void unregister() { providerReg.unregister(); providerReg = null; rules = null; } /** * This method creates a rule from template by using UID, templateUID and configuration. * * @return the created rule */ private Rule createACRule() { Configuration config = new Configuration(); config.put(CONFIG_UNIT, "Air Conditioner"); config.put(CONFIG_EXPECTED_RESULT, "The air conditioner is switched on."); config.put(AirConditionerRuleTemplate.CONFIG_TARGET_TEMPERATURE, new Integer(18)); config.put(AirConditionerRuleTemplate.CONFIG_OPERATION, TemperatureConditionType.OPERATOR_HEATING); Rule rule = new Rule(AC_UID); rule.setTemplateUID(AirConditionerRuleTemplate.UID); rule.setConfiguration(config); return rule; } /** * This method creates a rule from scratch by using trigger, condition, action, configDescriptions and * configuration, tags. * * @return the created rule */ private Rule createLightsRule() { // initialize the trigger String triggerId = "LightsSwitchOnRuleTrigger"; List<Trigger> triggers = new ArrayList<Trigger>(); triggers.add(new Trigger(triggerId, LightsTriggerType.UID, null)); // initialize the condition - here the tricky part is the referring into the condition input - trigger output. // The syntax is a similar to the JUEL syntax. Configuration config = new Configuration(); config.put(StateConditionType.CONFIG_STATE, "on"); List<Condition> conditions = new ArrayList<Condition>(); Map<String, String> inputs = new HashMap<String, String>(); inputs.put(StateConditionType.INPUT_CURRENT_STATE, triggerId + "." + StateConditionType.INPUT_CURRENT_STATE); conditions.add(new Condition("LightsStateCondition", StateConditionType.UID, config, inputs)); // initialize the action - here the tricky part is the referring into the action configuration parameter - the // template configuration parameter. The syntax is a similar to the JUEL syntax. config = new Configuration(); config.put(WelcomeHomeActionType.CONFIG_DEVICE, "Lights"); config.put(WelcomeHomeActionType.CONFIG_RESULT, "Lights are switched on"); List<Action> actions = new ArrayList<Action>(); actions.add(new Action("LightsSwitchOnAction", WelcomeHomeActionType.UID, config, null)); // initialize the configDescriptions List<ConfigDescriptionParameter> configDescriptions = new ArrayList<ConfigDescriptionParameter>(); final ConfigDescriptionParameter device = ConfigDescriptionParameterBuilder .create(WelcomeHomeRulesProvider.CONFIG_UNIT, Type.TEXT).withRequired(true).withReadOnly(true) .withMultiple(false).withLabel("Device").withDescription("Device description").build(); final ConfigDescriptionParameter result = ConfigDescriptionParameterBuilder .create(WelcomeHomeRulesProvider.CONFIG_EXPECTED_RESULT, Type.TEXT).withRequired(true) .withReadOnly(true).withMultiple(false).withLabel("Result").withDescription("Result description") .build(); configDescriptions.add(device); configDescriptions.add(result); // initialize the configuration config = new Configuration(); config.put(CONFIG_UNIT, "Lights"); config.put(CONFIG_EXPECTED_RESULT, "The lights are switched on."); // create the rule Rule lightsSwitchOn = new Rule(L_UID); lightsSwitchOn.setTriggers(triggers); lightsSwitchOn.setConfigurationDescriptions(configDescriptions); lightsSwitchOn.setConditions(conditions); lightsSwitchOn.setActions(actions); // initialize the tags Set<String> tags = new HashSet<String>(); tags.add("lights"); // set the tags lightsSwitchOn.setTags(tags); return lightsSwitchOn; } }