Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added group and system triggers to automation component #1509

Merged
merged 3 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
import org.openhab.core.automation.internal.module.handler.CompareConditionHandler;
import org.openhab.core.automation.internal.module.handler.GenericEventConditionHandler;
import org.openhab.core.automation.internal.module.handler.GenericEventTriggerHandler;
import org.openhab.core.automation.internal.module.handler.GroupCommandTriggerHandler;
import org.openhab.core.automation.internal.module.handler.GroupStateTriggerHandler;
import org.openhab.core.automation.internal.module.handler.ItemCommandActionHandler;
import org.openhab.core.automation.internal.module.handler.ItemCommandTriggerHandler;
import org.openhab.core.automation.internal.module.handler.ItemStateConditionHandler;
import org.openhab.core.automation.internal.module.handler.ItemStateTriggerHandler;
import org.openhab.core.automation.internal.module.handler.RuleEnablementActionHandler;
import org.openhab.core.automation.internal.module.handler.RunRuleActionHandler;
import org.openhab.core.automation.internal.module.handler.SystemTriggerHandler;
import org.openhab.core.automation.internal.module.handler.ThingStatusTriggerHandler;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.items.ItemRegistry;
Expand All @@ -56,12 +59,14 @@ public class CoreModuleHandlerFactory extends BaseModuleHandlerFactory implement
private final Logger logger = LoggerFactory.getLogger(CoreModuleHandlerFactory.class);

private static final Collection<String> TYPES = Arrays.asList(ItemCommandTriggerHandler.MODULE_TYPE_ID,
ItemStateTriggerHandler.UPDATE_MODULE_TYPE_ID, ItemStateTriggerHandler.CHANGE_MODULE_TYPE_ID,
ThingStatusTriggerHandler.UPDATE_MODULE_TYPE_ID, ThingStatusTriggerHandler.CHANGE_MODULE_TYPE_ID,
ItemStateConditionHandler.ITEM_STATE_CONDITION, ItemCommandActionHandler.ITEM_COMMAND_ACTION,
GenericEventTriggerHandler.MODULE_TYPE_ID, ChannelEventTriggerHandler.MODULE_TYPE_ID,
GenericEventConditionHandler.MODULETYPE_ID, GenericEventConditionHandler.MODULETYPE_ID,
CompareConditionHandler.MODULE_TYPE, RuleEnablementActionHandler.UID, RunRuleActionHandler.UID);
GroupCommandTriggerHandler.MODULE_TYPE_ID, ItemStateTriggerHandler.UPDATE_MODULE_TYPE_ID,
ItemStateTriggerHandler.CHANGE_MODULE_TYPE_ID, GroupStateTriggerHandler.UPDATE_MODULE_TYPE_ID,
GroupStateTriggerHandler.CHANGE_MODULE_TYPE_ID, ThingStatusTriggerHandler.UPDATE_MODULE_TYPE_ID,
ThingStatusTriggerHandler.CHANGE_MODULE_TYPE_ID, ItemStateConditionHandler.ITEM_STATE_CONDITION,
ItemCommandActionHandler.ITEM_COMMAND_ACTION, GenericEventTriggerHandler.MODULE_TYPE_ID,
ChannelEventTriggerHandler.MODULE_TYPE_ID, GenericEventConditionHandler.MODULETYPE_ID,
GenericEventConditionHandler.MODULETYPE_ID, CompareConditionHandler.MODULE_TYPE,
SystemTriggerHandler.STARTLEVEL_MODULE_TYPE_ID, RuleEnablementActionHandler.UID, RunRuleActionHandler.UID);

private ItemRegistry itemRegistry;
private EventPublisher eventPublisher;
Expand Down Expand Up @@ -97,6 +102,10 @@ protected void setItemRegistry(ItemRegistry itemRegistry) {
((ItemStateConditionHandler) handler).setItemRegistry(this.itemRegistry);
} else if (handler instanceof ItemCommandActionHandler) {
((ItemCommandActionHandler) handler).setItemRegistry(this.itemRegistry);
} else if (handler instanceof GroupCommandTriggerHandler) {
((GroupCommandTriggerHandler) handler).setItemRegistry(this.itemRegistry);
} else if (handler instanceof GroupStateTriggerHandler) {
((GroupStateTriggerHandler) handler).setItemRegistry(this.itemRegistry);
}
}
}
Expand All @@ -112,6 +121,10 @@ protected void unsetItemRegistry(ItemRegistry itemRegistry) {
((ItemStateConditionHandler) handler).unsetItemRegistry(this.itemRegistry);
} else if (handler instanceof ItemCommandActionHandler) {
((ItemCommandActionHandler) handler).unsetItemRegistry(this.itemRegistry);
} else if (handler instanceof GroupCommandTriggerHandler) {
((GroupCommandTriggerHandler) handler).unsetItemRegistry(this.itemRegistry);
} else if (handler instanceof GroupStateTriggerHandler) {
((GroupStateTriggerHandler) handler).unsetItemRegistry(this.itemRegistry);
}
}
this.itemRegistry = null;
Expand Down Expand Up @@ -158,12 +171,24 @@ protected synchronized ModuleHandler internalCreate(final Module module, final S
return new ChannelEventTriggerHandler((Trigger) module, bundleContext);
} else if (ItemCommandTriggerHandler.MODULE_TYPE_ID.equals(moduleTypeUID)) {
return new ItemCommandTriggerHandler((Trigger) module, bundleContext);
} else if (SystemTriggerHandler.STARTLEVEL_MODULE_TYPE_ID.equals(moduleTypeUID)) {
return new SystemTriggerHandler((Trigger) module, bundleContext);
} else if (ThingStatusTriggerHandler.CHANGE_MODULE_TYPE_ID.equals(moduleTypeUID)
|| ThingStatusTriggerHandler.UPDATE_MODULE_TYPE_ID.equals(moduleTypeUID)) {
return new ThingStatusTriggerHandler((Trigger) module, bundleContext);
} else if (ItemStateTriggerHandler.CHANGE_MODULE_TYPE_ID.equals(moduleTypeUID)
|| ItemStateTriggerHandler.UPDATE_MODULE_TYPE_ID.equals(moduleTypeUID)) {
return new ItemStateTriggerHandler((Trigger) module, bundleContext);
} else if (GroupCommandTriggerHandler.MODULE_TYPE_ID.equals(moduleTypeUID)) {
final GroupCommandTriggerHandler handler = new GroupCommandTriggerHandler((Trigger) module,
bundleContext);
handler.setItemRegistry(itemRegistry);
return handler;
} else if (GroupStateTriggerHandler.CHANGE_MODULE_TYPE_ID.equals(moduleTypeUID)
|| GroupStateTriggerHandler.UPDATE_MODULE_TYPE_ID.equals(moduleTypeUID)) {
final GroupStateTriggerHandler handler = new GroupStateTriggerHandler((Trigger) module, bundleContext);
handler.setItemRegistry(itemRegistry);
return handler;
}
} else if (module instanceof Condition) {
// Handle conditions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public synchronized void dispose() {

@Override
public void run() {
((TriggerHandlerCallback) callback).triggered(module, null);
if (callback != null) {
((TriggerHandlerCallback) callback).triggered(module, null);
} else {
logger.debug("Tried to trigger, but callback isn't available!");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.core.automation.internal.module.handler;

import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.Trigger;
import org.openhab.core.automation.handler.BaseTriggerModuleHandler;
import org.openhab.core.automation.handler.TriggerHandlerCallback;
import org.openhab.core.events.Event;
import org.openhab.core.events.EventFilter;
import org.openhab.core.events.EventSubscriber;
import org.openhab.core.items.Item;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.items.events.ItemCommandEvent;
import org.openhab.core.types.Command;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is an ModuleHandler implementation for Triggers which trigger the rule
* if a member of an item group receives a command.
* The group name and command value can be set with the configuration.
*
* @author Kai Kreuzer - Initial contribution
*/
@NonNullByDefault
public class GroupCommandTriggerHandler extends BaseTriggerModuleHandler implements EventSubscriber, EventFilter {
cweitkamp marked this conversation as resolved.
Show resolved Hide resolved

private final Logger logger = LoggerFactory.getLogger(GroupCommandTriggerHandler.class);

private final String groupName;
private final String command;
private final String topic;

private final Set<String> types;
private final BundleContext bundleContext;

public static final String MODULE_TYPE_ID = "core.GroupCommandTrigger";

private static final String CFG_GROUPNAME = "groupName";
private static final String CFG_COMMAND = "command";

private ServiceRegistration<?> eventSubscriberRegistration;
private @Nullable ItemRegistry itemRegistry;

public GroupCommandTriggerHandler(Trigger module, BundleContext bundleContext) {
super(module);
this.groupName = (String) module.getConfiguration().get(CFG_GROUPNAME);
this.command = (String) module.getConfiguration().get(CFG_COMMAND);
this.types = Collections.singleton(ItemCommandEvent.TYPE);
this.bundleContext = bundleContext;
Dictionary<String, Object> properties = new Hashtable<>();
this.topic = "smarthome/items/";
properties.put("event.topics", topic);
eventSubscriberRegistration = this.bundleContext.registerService(EventSubscriber.class.getName(), this,
properties);
}

@Override
public Set<String> getSubscribedEventTypes() {
return types;
}

@Override
public @Nullable EventFilter getEventFilter() {
return this;
}

@Override
public void receive(Event event) {
if (callback instanceof TriggerHandlerCallback) {
TriggerHandlerCallback cb = (TriggerHandlerCallback) callback;
logger.trace("Received Event: Source: {} Topic: {} Type: {} Payload: {}", event.getSource(),
event.getTopic(), event.getType(), event.getPayload());
Map<String, Object> values = new HashMap<>();
if (event instanceof ItemCommandEvent) {
ItemCommandEvent icEvent = (ItemCommandEvent) event;
String itemName = icEvent.getItemName();
if (itemRegistry != null) {
Item item = itemRegistry.get(itemName);
if (item != null && item.getGroupNames().contains(groupName)) {
Command command = icEvent.getItemCommand();
if (this.command.equals(command.toFullString())) {
values.put("triggeringItem", item);
values.put("command", command);
values.put("event", event);
cb.triggered(this.module, values);
}
}
}
}
}
}

/**
* do the cleanup: unregistering eventSubscriber...
*/
@Override
public void dispose() {
super.dispose();
eventSubscriberRegistration.unregister();
}

@Override
public boolean apply(Event event) {
logger.trace("->FILTER: {}", event.getTopic());
return event.getTopic().startsWith(topic);
}

public void setItemRegistry(ItemRegistry itemRegistry) {
this.itemRegistry = itemRegistry;
}

public void unsetItemRegistry(ItemRegistry itemRegistry) {
this.itemRegistry = null;
}
}
Loading