Add group name to GroupStateTriggerHandler (#3536)

* Add group name to GroupStateTriggerHandler

When triggering on state change/update of group member, the group is not available in the rule context (because the event is the `ItemStateChanged/UpdatedEvent` that caused the group to change/update. This adds a new element `triggeringGroup` to the rule context.

This is useful for generalized rules that trigger on different groups.

Signed-off-by: Jan N. Klug <github@klug.nrw>
pull/3637/head
J-N-K 2023-05-27 21:30:34 +02:00 committed by GitHub
parent ed392eec86
commit 7843b6872a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 1 deletions

View File

@ -106,10 +106,14 @@ public class GroupCommandTriggerHandler extends BaseTriggerModuleHandler impleme
if (event instanceof ItemCommandEvent icEvent) { if (event instanceof ItemCommandEvent icEvent) {
String itemName = icEvent.getItemName(); String itemName = icEvent.getItemName();
Item item = itemRegistry.get(itemName); Item item = itemRegistry.get(itemName);
Item group = itemRegistry.get(groupName);
if (item != null && item.getGroupNames().contains(groupName)) { if (item != null && item.getGroupNames().contains(groupName)) {
String command = this.command; String command = this.command;
Command itemCommand = icEvent.getItemCommand(); Command itemCommand = icEvent.getItemCommand();
if (command == null || command.equals(itemCommand.toFullString())) { if (command == null || command.equals(itemCommand.toFullString())) {
if (group != null) {
values.put("triggeringGroup", group);
}
values.put("triggeringItem", item); values.put("triggeringItem", item);
values.put("command", itemCommand); values.put("command", itemCommand);
values.put("event", event); values.put("event", event);

View File

@ -115,10 +115,14 @@ public class GroupStateTriggerHandler extends BaseTriggerModuleHandler implement
if (event instanceof ItemStateUpdatedEvent isEvent && UPDATE_MODULE_TYPE_ID.equals(module.getTypeUID())) { if (event instanceof ItemStateUpdatedEvent isEvent && UPDATE_MODULE_TYPE_ID.equals(module.getTypeUID())) {
String itemName = isEvent.getItemName(); String itemName = isEvent.getItemName();
Item item = itemRegistry.get(itemName); Item item = itemRegistry.get(itemName);
Item group = itemRegistry.get(groupName);
if (item != null && item.getGroupNames().contains(groupName)) { if (item != null && item.getGroupNames().contains(groupName)) {
State state = isEvent.getItemState(); State state = isEvent.getItemState();
if ((this.state == null || state.toFullString().equals(this.state))) { if ((this.state == null || state.toFullString().equals(this.state))) {
Map<String, Object> values = new HashMap<>(); Map<String, Object> values = new HashMap<>();
if (group != null) {
values.put("triggeringGroup", group);
}
values.put("triggeringItem", item); values.put("triggeringItem", item);
values.put("state", state); values.put("state", state);
values.put("event", event); values.put("event", event);
@ -129,12 +133,16 @@ public class GroupStateTriggerHandler extends BaseTriggerModuleHandler implement
&& CHANGE_MODULE_TYPE_ID.equals(module.getTypeUID())) { && CHANGE_MODULE_TYPE_ID.equals(module.getTypeUID())) {
String itemName = iscEvent.getItemName(); String itemName = iscEvent.getItemName();
Item item = itemRegistry.get(itemName); Item item = itemRegistry.get(itemName);
Item group = itemRegistry.get(groupName);
if (item != null && item.getGroupNames().contains(groupName)) { if (item != null && item.getGroupNames().contains(groupName)) {
State state = iscEvent.getItemState(); State state = iscEvent.getItemState();
State oldState = iscEvent.getOldItemState(); State oldState = iscEvent.getOldItemState();
if (stateMatches(this.state, state) && stateMatches(this.previousState, oldState)) { if (stateMatches(this.state, state) && stateMatches(this.previousState, oldState)) {
Map<String, Object> values = new HashMap<>(); Map<String, Object> values = new HashMap<>();
if (group != null) {
values.put("triggeringGroup", group);
}
values.put("triggeringItem", item); values.put("triggeringItem", item);
values.put("oldState", oldState); values.put("oldState", oldState);
values.put("newState", state); values.put("newState", state);

View File

@ -290,6 +290,15 @@
} }
], ],
"outputs": [ "outputs": [
{
"name": "triggeringGroup",
"type": "org.openhab.core.items.Item",
"description": "the group that the item belongs to",
"label": "Triggering Group",
"tags": [
"item"
]
},
{ {
"name": "triggeringItem", "name": "triggeringItem",
"type": "org.openhab.core.items.Item", "type": "org.openhab.core.items.Item",
@ -366,6 +375,15 @@
} }
], ],
"outputs": [ "outputs": [
{
"name": "triggeringGroup",
"type": "org.openhab.core.items.Item",
"description": "the group that the item belongs to",
"label": "Triggering Group",
"tags": [
"item"
]
},
{ {
"name": "triggeringItem", "name": "triggeringItem",
"type": "org.openhab.core.items.Item", "type": "org.openhab.core.items.Item",

View File

@ -66,6 +66,8 @@ module-type.core.GroupCommandTrigger.config.command.option.OPEN = OPEN
module-type.core.GroupCommandTrigger.config.command.option.CLOSED = CLOSED module-type.core.GroupCommandTrigger.config.command.option.CLOSED = CLOSED
module-type.core.GroupCommandTrigger.config.command.option.UP = UP module-type.core.GroupCommandTrigger.config.command.option.UP = UP
module-type.core.GroupCommandTrigger.config.command.option.DOWN = DOWN module-type.core.GroupCommandTrigger.config.command.option.DOWN = DOWN
module-type.core.GroupCommandTrigger.output.triggeringGroup.label = Triggering Group
module-type.core.GroupCommandTrigger.output.triggeringGroup.description = the group that the item belongs to
module-type.core.GroupCommandTrigger.output.triggeringItem.label = Triggering Item module-type.core.GroupCommandTrigger.output.triggeringItem.label = Triggering Item
module-type.core.GroupCommandTrigger.output.triggeringItem.description = the member of the group that received the command module-type.core.GroupCommandTrigger.output.triggeringItem.description = the member of the group that received the command
module-type.core.GroupCommandTrigger.output.command.label = Command module-type.core.GroupCommandTrigger.output.command.label = Command
@ -118,6 +120,8 @@ module-type.core.GroupStateUpdateTrigger.config.state.option.OPEN = OPEN
module-type.core.GroupStateUpdateTrigger.config.state.option.CLOSED = CLOSED module-type.core.GroupStateUpdateTrigger.config.state.option.CLOSED = CLOSED
module-type.core.GroupStateUpdateTrigger.config.state.option.UP = UP module-type.core.GroupStateUpdateTrigger.config.state.option.UP = UP
module-type.core.GroupStateUpdateTrigger.config.state.option.DOWN = DOWN module-type.core.GroupStateUpdateTrigger.config.state.option.DOWN = DOWN
module-type.core.GroupStateUpdateTrigger.output.triggeringGroup.label = Triggering Group
module-type.core.GroupStateUpdateTrigger.output.triggeringGroup.description = the group that the item belongs to
module-type.core.GroupStateUpdateTrigger.output.triggeringItem.label = Triggering Item module-type.core.GroupStateUpdateTrigger.output.triggeringItem.label = Triggering Item
module-type.core.GroupStateUpdateTrigger.output.triggeringItem.description = the member of the group that updated its state module-type.core.GroupStateUpdateTrigger.output.triggeringItem.description = the member of the group that updated its state
module-type.core.GroupStateUpdateTrigger.output.state.label = State module-type.core.GroupStateUpdateTrigger.output.state.label = State

View File

@ -32,6 +32,7 @@ import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.interpreter.IEvaluationContext; import org.eclipse.xtext.xbase.interpreter.IEvaluationContext;
import org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext; import org.eclipse.xtext.xbase.interpreter.impl.DefaultEvaluationContext;
import org.openhab.core.automation.module.script.ScriptExtensionAccessor; import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
import org.openhab.core.items.Item;
import org.openhab.core.items.events.ItemEvent; import org.openhab.core.items.events.ItemEvent;
import org.openhab.core.model.script.engine.Script; import org.openhab.core.model.script.engine.Script;
import org.openhab.core.model.script.engine.ScriptExecutionException; import org.openhab.core.model.script.engine.ScriptExecutionException;
@ -63,7 +64,8 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
private static final Map<String, String> IMPLICIT_VARS = Map.of("command", private static final Map<String, String> IMPLICIT_VARS = Map.of("command",
ScriptJvmModelInferrer.VAR_RECEIVED_COMMAND, "state", ScriptJvmModelInferrer.VAR_NEW_STATE, "newState", ScriptJvmModelInferrer.VAR_RECEIVED_COMMAND, "state", ScriptJvmModelInferrer.VAR_NEW_STATE, "newState",
ScriptJvmModelInferrer.VAR_NEW_STATE, "oldState", ScriptJvmModelInferrer.VAR_PREVIOUS_STATE, ScriptJvmModelInferrer.VAR_NEW_STATE, "oldState", ScriptJvmModelInferrer.VAR_PREVIOUS_STATE,
"triggeringItem", ScriptJvmModelInferrer.VAR_TRIGGERING_ITEM, "input", ScriptJvmModelInferrer.VAR_INPUT); "triggeringItem", ScriptJvmModelInferrer.VAR_TRIGGERING_ITEM, "triggeringGroup",
ScriptJvmModelInferrer.VAR_TRIGGERING_GROUP, "input", ScriptJvmModelInferrer.VAR_INPUT);
private final Logger logger = LoggerFactory.getLogger(DSLScriptEngine.class); private final Logger logger = LoggerFactory.getLogger(DSLScriptEngine.class);
@ -179,6 +181,11 @@ public class DSLScriptEngine implements javax.script.ScriptEngine {
if (value instanceof ItemEvent event) { if (value instanceof ItemEvent event) {
evalContext.newValue(QualifiedName.create(ScriptJvmModelInferrer.VAR_TRIGGERING_ITEM_NAME), evalContext.newValue(QualifiedName.create(ScriptJvmModelInferrer.VAR_TRIGGERING_ITEM_NAME),
event.getItemName()); event.getItemName());
Object group = context.getAttribute(ScriptJvmModelInferrer.VAR_TRIGGERING_GROUP);
if (group instanceof Item groupItem) {
evalContext.newValue(QualifiedName.create(ScriptJvmModelInferrer.VAR_TRIGGERING_GROUP_NAME),
groupItem.getName());
}
} }
if (value instanceof ThingStatusInfoChangedEvent event) { if (value instanceof ThingStatusInfoChangedEvent event) {
evalContext.newValue(QualifiedName.create(ScriptJvmModelInferrer.VAR_TRIGGERING_THING), evalContext.newValue(QualifiedName.create(ScriptJvmModelInferrer.VAR_TRIGGERING_THING),

View File

@ -44,6 +44,12 @@ class ScriptJvmModelInferrer extends AbstractModelInferrer {
/** Variable name for the input string in a "script transformation" or "script profile" */ /** Variable name for the input string in a "script transformation" or "script profile" */
public static final String VAR_INPUT = "input"; public static final String VAR_INPUT = "input";
/** Variable name for the group in a "member of state triggered" or "member of command triggered" rule */
public static final String VAR_TRIGGERING_GROUP = "triggeringGroup";
/** Variable name for the group in a "member of state triggered" or "member of command triggered" rule */
public static final String VAR_TRIGGERING_GROUP_NAME = "triggeringGroupName";
/** Variable name for the item in a "state triggered" or "command triggered" rule */ /** Variable name for the item in a "state triggered" or "command triggered" rule */
public static final String VAR_TRIGGERING_ITEM = "triggeringItem"; public static final String VAR_TRIGGERING_ITEM = "triggeringItem";
@ -131,6 +137,10 @@ class ScriptJvmModelInferrer extends AbstractModelInferrer {
static = true static = true
val inputTypeRef = script.newTypeRef(String) val inputTypeRef = script.newTypeRef(String)
parameters += script.toParameter(VAR_INPUT, inputTypeRef) parameters += script.toParameter(VAR_INPUT, inputTypeRef)
val groupTypeRef = script.newTypeRef(Item)
parameters += script.toParameter(VAR_TRIGGERING_GROUP, groupTypeRef)
val groupNameRef = script.newTypeRef(String)
parameters += script.toParameter(VAR_TRIGGERING_GROUP_NAME, groupNameRef)
val itemTypeRef = script.newTypeRef(Item) val itemTypeRef = script.newTypeRef(Item)
parameters += script.toParameter(VAR_TRIGGERING_ITEM, itemTypeRef) parameters += script.toParameter(VAR_TRIGGERING_ITEM, itemTypeRef)
val itemNameRef = script.newTypeRef(String) val itemNameRef = script.newTypeRef(String)