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

enrich memberOf with options to just listen on items or groups #95

Merged
merged 8 commits into from
Feb 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.openhab.automation.jrule.exception.JRuleItemNotFoundException;
import org.openhab.automation.jrule.exception.JRuleRuntimeException;
import org.openhab.automation.jrule.internal.JRuleConfig;
import org.openhab.automation.jrule.internal.JRuleLog;
import org.openhab.automation.jrule.internal.engine.excutioncontext.JRuleChannelExecutionContext;
Expand All @@ -55,6 +56,7 @@
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleCondition;
import org.openhab.automation.jrule.rules.JRuleLogName;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRulePrecondition;
import org.openhab.automation.jrule.rules.JRuleTag;
Expand Down Expand Up @@ -272,6 +274,14 @@ private JRuleItemExecutionContext.JRuleAdditionalItemCheckData getAdditionalChec
.orElse(new JRuleItemExecutionContext.JRuleAdditionalItemCheckData(List.of()));
}

private Item getItem(String name) {
try {
return itemRegistry.getItem(name);
} catch (ItemNotFoundException e) {
throw new JRuleRuntimeException(String.format("cannot find item: %s", name), e);
}
}

public boolean matchPrecondition(JRuleExecutionContext jRuleExecutionContext) {
return jRuleExecutionContext.getPreconditionContextList().stream().allMatch(context -> {
final Item item;
Expand Down Expand Up @@ -343,18 +353,14 @@ public synchronized void reset() {
}

public boolean watchingForItem(String itemName) {
List<String> belongingGroups = Optional.of(itemName).map(s -> {
try {
return itemRegistry.getItem(s);
} catch (ItemNotFoundException e) {
throw new IllegalStateException("this can never occur", e);
}
}).map(Item::getGroupNames).orElse(List.of());
List<String> parentGroups = Optional.of(itemName).map(this::getItem).map(Item::getGroupNames).orElse(List.of());

boolean b = this.contextList.stream().filter(context -> context instanceof JRuleItemExecutionContext)
.map(context -> ((JRuleItemExecutionContext) context))
.anyMatch(context -> (context.getItemName().equals(itemName) && !context.isMemberOf())
|| (belongingGroups.contains(context.getItemName()) && context.isMemberOf()));
.anyMatch(context -> (context.getItemName().equals(itemName)
&& context.getMemberOf() == JRuleMemberOf.None)
|| (parentGroups.contains(context.getItemName())
&& context.getMemberOf() != JRuleMemberOf.None));
logDebug("watching for item: '{}'? -> {}", itemName, b);
return b;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.openhab.automation.jrule.internal.handler.JRuleEventHandler;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.automation.jrule.rules.event.JRuleEvent;
import org.openhab.automation.jrule.rules.event.JRuleItemEvent;
import org.openhab.core.events.AbstractEvent;
Expand All @@ -40,7 +41,7 @@ public class JRuleItemChangeExecutionContext extends JRuleItemExecutionContext {
private final Optional<JRuleConditionContext> previousConditionContext;

public JRuleItemChangeExecutionContext(JRule jRule, String logName, String[] loggingTags, Method method,
String itemName, boolean memberOf, Optional<JRuleConditionContext> conditionContext,
String itemName, JRuleMemberOf memberOf, Optional<JRuleConditionContext> conditionContext,
Optional<JRuleConditionContext> previousConditionContext,
List<JRulePreconditionContext> preconditionContextList, Optional<String> from, Optional<String> to) {
super(jRule, logName, loggingTags, method, itemName, memberOf, conditionContext, preconditionContextList);
Expand All @@ -63,28 +64,41 @@ && matchCondition(((ItemStateChangedEvent) event).getItemState().toString(),
&& to.map(s -> ((ItemStateChangedEvent) event).getItemState().toString().equals(s)).orElse(true))) {
return false;
}
if (!isMemberOf() && ((ItemStateChangedEvent) event).getItemName().equals(this.getItemName())) {
if (getMemberOf() == JRuleMemberOf.None
&& ((ItemStateChangedEvent) event).getItemName().equals(this.getItemName())) {
return true;
}
if (isMemberOf() && checkData instanceof JRuleAdditionalItemCheckData
&& ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName())) {
return true;
if (getMemberOf() != JRuleMemberOf.None && checkData instanceof JRuleAdditionalItemCheckData) {
switch (getMemberOf()) {
case All:
return true;
case Groups:
return ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName());
case Items:
return !((JRuleAdditionalItemCheckData) checkData).getBelongingGroups()
.contains(this.getItemName());
default:
return false;
}
}
return false;
}

@Override
public JRuleEvent createJRuleEvent(AbstractEvent event) {
final String itemName;
final String memberName;
if (isMemberOf()) {
if (getMemberOf() != JRuleMemberOf.None) {
itemName = this.getItemName();
memberName = ((ItemEvent) event).getItemName();
} else {
itemName = this.getItemName();
memberName = event instanceof GroupItemStateChangedEvent
? ((GroupItemStateChangedEvent) event).getMemberName()
: null;
}

return new JRuleItemEvent(this.getItemName(), memberName,
return new JRuleItemEvent(itemName, memberName,
JRuleEventHandler.get().toValue(((ItemStateChangedEvent) event).getItemState()),
JRuleEventHandler.get().toValue(((ItemStateChangedEvent) event).getOldItemState()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.commons.lang3.math.NumberUtils;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleCondition;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.core.library.types.QuantityType;

/**
Expand All @@ -29,11 +30,11 @@
*/
public abstract class JRuleItemExecutionContext extends JRuleExecutionContext {
protected final String itemName;
protected final boolean memberOf;
protected final JRuleMemberOf memberOf;
protected final Optional<JRuleConditionContext> conditionContext;

public JRuleItemExecutionContext(JRule jRule, String logName, String[] loggingTags, Method method, String itemName,
boolean memberOf, Optional<JRuleConditionContext> conditionContext,
JRuleMemberOf memberOf, Optional<JRuleConditionContext> conditionContext,
List<JRulePreconditionContext> preconditionContextList) {
super(jRule, logName, loggingTags, method, preconditionContextList);
this.itemName = itemName;
Expand All @@ -49,7 +50,7 @@ public boolean matchCondition(String state, String previousState) {
return conditionContext.map(c -> c.matchCondition(state)).orElse(true);
}

public boolean isMemberOf() {
public JRuleMemberOf getMemberOf() {
return memberOf;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@

import org.openhab.automation.jrule.internal.handler.JRuleEventHandler;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.automation.jrule.rules.event.JRuleEvent;
import org.openhab.automation.jrule.rules.event.JRuleItemEvent;
import org.openhab.core.events.AbstractEvent;
import org.openhab.core.items.events.ItemCommandEvent;
import org.openhab.core.items.events.ItemEvent;
import org.openhab.core.items.events.ItemStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,7 +39,7 @@ public class JRuleItemReceivedCommandExecutionContext extends JRuleItemExecution
protected final Optional<String> command;

public JRuleItemReceivedCommandExecutionContext(JRule jRule, String logName, String[] loggingTags, Method method,
String itemName, boolean memberOf, Optional<JRuleConditionContext> conditionContext,
String itemName, JRuleMemberOf memberOf, Optional<JRuleConditionContext> conditionContext,
List<JRulePreconditionContext> preconditionContextList, Optional<String> command) {
super(jRule, logName, loggingTags, method, itemName, memberOf, conditionContext, preconditionContextList);
this.command = command;
Expand All @@ -51,27 +53,40 @@ && matchCondition(((ItemCommandEvent) event).getItemCommand().toString(), null)
return false;
}

if (!isMemberOf() && ((ItemCommandEvent) event).getItemName().equals(this.getItemName())) {
if (getMemberOf() == JRuleMemberOf.None
&& ((ItemCommandEvent) event).getItemName().equals(this.getItemName())) {
return true;
}
if (isMemberOf() && checkData instanceof JRuleAdditionalItemCheckData
&& ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName())) {
return true;
if (getMemberOf() != JRuleMemberOf.None && checkData instanceof JRuleAdditionalItemCheckData) {
switch (getMemberOf()) {
case All:
return true;
case Groups:
return ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName());
case Items:
return !((JRuleAdditionalItemCheckData) checkData).getBelongingGroups()
.contains(this.getItemName());
default:
return false;
}
}
return false;
}

@Override
public JRuleEvent createJRuleEvent(AbstractEvent event) {
final String itemName;
final String memberName;
if (isMemberOf()) {
if (getMemberOf() != JRuleMemberOf.None) {
memberName = ((ItemEvent) event).getItemName();
itemName = ((ItemEvent) event).getItemName();
} else {
memberName = null;
itemName = this.getItemName();
}

return new JRuleItemEvent(this.getItemName(), memberName,
JRuleEventHandler.get().toValue(((ItemCommandEvent) event).getItemCommand()), null);
return new JRuleItemEvent(itemName, memberName,
JRuleEventHandler.get().toValue(((ItemStateEvent) event).getItemState()), null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.openhab.automation.jrule.internal.handler.JRuleEventHandler;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.automation.jrule.rules.event.JRuleEvent;
import org.openhab.automation.jrule.rules.event.JRuleItemEvent;
import org.openhab.core.events.AbstractEvent;
Expand All @@ -37,7 +38,7 @@ public class JRuleItemReceivedUpdateExecutionContext extends JRuleItemExecutionC
private final Optional<String> state;

public JRuleItemReceivedUpdateExecutionContext(JRule jRule, String logName, String[] loggingTags, Method method,
String itemName, boolean memberOf, Optional<JRuleConditionContext> conditionContext,
String itemName, JRuleMemberOf memberOf, Optional<JRuleConditionContext> conditionContext,
List<JRulePreconditionContext> preconditionContextList, Optional<String> state) {
super(jRule, logName, loggingTags, method, itemName, memberOf, conditionContext, preconditionContextList);
this.state = state;
Expand All @@ -50,26 +51,38 @@ && matchCondition(((ItemStateEvent) event).getItemState().toString(), null)
&& state.map(s -> ((ItemStateEvent) event).getItemState().toString().equals(s)).orElse(true))) {
return false;
}
if (!isMemberOf() && ((ItemStateEvent) event).getItemName().equals(this.getItemName())) {
if (getMemberOf() == JRuleMemberOf.None && ((ItemStateEvent) event).getItemName().equals(this.getItemName())) {
return true;
}
if (isMemberOf() && checkData instanceof JRuleAdditionalItemCheckData
&& ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName())) {
return true;
if (getMemberOf() != JRuleMemberOf.None && checkData instanceof JRuleAdditionalItemCheckData) {
switch (getMemberOf()) {
case All:
return true;
case Groups:
return ((JRuleAdditionalItemCheckData) checkData).getBelongingGroups().contains(this.getItemName());
case Items:
return !((JRuleAdditionalItemCheckData) checkData).getBelongingGroups()
.contains(this.getItemName());
default:
return false;
}
}
return false;
}

@Override
public JRuleEvent createJRuleEvent(AbstractEvent event) {
final String itemName;
final String memberName;
if (isMemberOf()) {
if (getMemberOf() != JRuleMemberOf.None) {
memberName = ((ItemEvent) event).getItemName();
itemName = ((ItemEvent) event).getItemName();
} else {
memberName = null;
itemName = this.getItemName();
}

return new JRuleItemEvent(this.getItemName(), memberName,
return new JRuleItemEvent(itemName, memberName,
JRuleEventHandler.get().toValue(((ItemStateEvent) event).getItemState()), null);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2010-2022 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.automation.jrule.rules;

/**
* The {@link JRuleMemberOf}
*
* @author Robert Delbrück
*/
public enum JRuleMemberOf {
/**
* Not using memberOf
*/
None,
/**
* Listen on all child items
*/
All,
/**
* Just listen on child groups
*/
Groups,
/**
* Just listen on concrete Items (without groups)
*/
Items
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

String to() default "";

boolean memberOf() default false;
JRuleMemberOf memberOf() default JRuleMemberOf.None;

JRuleCondition condition() default @JRuleCondition;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

String command() default "";

boolean memberOf() default false;
JRuleMemberOf memberOf() default JRuleMemberOf.None;

JRuleCondition condition() default @JRuleCondition;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

String state() default "";

boolean memberOf() default false;
JRuleMemberOf memberOf() default JRuleMemberOf.None;

JRuleCondition condition() default @JRuleCondition;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.openhab.automation.jrule.items.JRuleSwitchItem;
import org.openhab.automation.jrule.rules.JRule;
import org.openhab.automation.jrule.rules.JRuleCondition;
import org.openhab.automation.jrule.rules.JRuleMemberOf;
import org.openhab.automation.jrule.rules.JRuleName;
import org.openhab.automation.jrule.rules.JRulePrecondition;
import org.openhab.automation.jrule.rules.JRuleWhenChannelTrigger;
Expand Down Expand Up @@ -178,20 +179,20 @@ public void mqttThingChangedToOffline(JRuleThingEvent event) {
}

@JRuleName(NAME_MEMBER_OF_GROUP_RECEIVED_COMMAND)
@JRuleWhenItemReceivedCommand(item = ITEM_SWITCH_GROUP, memberOf = true)
@JRuleWhenItemReceivedCommand(item = ITEM_SWITCH_GROUP, memberOf = JRuleMemberOf.All)
public synchronized void memberOfGroupReceivedCommand(JRuleItemEvent event) {
logInfo("Member of Group ({}) received command", event.getMemberName());
}

@JRuleName(NAME_MEMBER_OF_GROUP_RECEIVED_UPDATE)
@JRuleWhenItemReceivedUpdate(item = ITEM_SWITCH_GROUP, memberOf = true)
@JRuleWhenItemReceivedUpdate(item = ITEM_SWITCH_GROUP, memberOf = JRuleMemberOf.All)
public synchronized void memberOfGroupReceivedUpdate(JRuleItemEvent event) {
final String memberThatChangedStatus = event.getMemberName();
logInfo("Member of Group ({}) received update", event.getMemberName());
}

@JRuleName(NAME_MEMBER_OF_GROUP_CHANGED)
@JRuleWhenItemChange(item = ITEM_SWITCH_GROUP, memberOf = true)
@JRuleWhenItemChange(item = ITEM_SWITCH_GROUP, memberOf = JRuleMemberOf.All)
public synchronized void memberOfGroupChanged(JRuleItemEvent event) {
final String memberThatChangedStatus = event.getMemberName();
logInfo("Member of Group ({}) changed", event.getMemberName());
Expand Down
Loading