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

[automation] Allow UoM in 'ItemStateCondition' #2435

Merged
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 @@ -12,7 +12,6 @@
*/
package org.openhab.core.automation.internal;

import java.util.Collections;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand All @@ -33,7 +32,7 @@
@NonNullByDefault
public class ActionImpl extends ModuleImpl implements Action {

private Map<String, String> inputs = Collections.emptyMap();
private Map<String, String> inputs = Map.of();

/**
* Constructor of Action object.
Expand All @@ -48,7 +47,7 @@ public class ActionImpl extends ModuleImpl implements Action {
public ActionImpl(String UID, String typeUID, @Nullable Configuration configuration, @Nullable String label,
@Nullable String description, @Nullable Map<String, String> inputs) {
super(UID, typeUID, configuration, label, description);
this.inputs = inputs == null ? Collections.emptyMap() : Collections.unmodifiableMap(inputs);
this.inputs = inputs == null ? Map.of() : Map.copyOf(inputs);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/
package org.openhab.core.automation.internal;

import java.util.Collections;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand All @@ -31,7 +30,7 @@
@NonNullByDefault
public class ConditionImpl extends ModuleImpl implements Condition {

private Map<String, String> inputs = Collections.emptyMap();
private Map<String, String> inputs = Map.of();

/**
* Constructor of {@link Condition} module object.
Expand All @@ -46,7 +45,7 @@ public class ConditionImpl extends ModuleImpl implements Condition {
public ConditionImpl(String id, String typeUID, @Nullable Configuration configuration, @Nullable String label,
@Nullable String description, @Nullable Map<String, String> inputs) {
super(id, typeUID, configuration, label, description);
this.inputs = inputs == null ? Collections.emptyMap() : Collections.unmodifiableMap(inputs);
this.inputs = inputs == null ? Map.of() : Map.copyOf(inputs);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@

import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.Condition;
import org.openhab.core.automation.handler.BaseConditionModuleHandler;
import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.types.State;
import org.openhab.core.types.TypeParser;
import org.slf4j.Logger;
Expand All @@ -31,21 +34,21 @@
* @author Benedikt Niehues - Initial contribution
* @author Kai Kreuzer - refactored and simplified customized module handling
*/
@NonNullByDefault
public class ItemStateConditionHandler extends BaseConditionModuleHandler {

/**
* Constants for Config-Parameters corresponding to Definition in
* ItemModuleTypeDefinition.json
* Constants for Config-Parameters corresponding to Definition in ItemModuleTypeDefinition.json
*/
private static final String ITEM_NAME = "itemName";
private static final String OPERATOR = "operator";
private static final String STATE = "state";
public static final String ITEM_NAME = "itemName";
public static final String OPERATOR = "operator";
public static final String STATE = "state";

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

public static final String ITEM_STATE_CONDITION = "core.ItemStateCondition";

private ItemRegistry itemRegistry;
private @Nullable ItemRegistry itemRegistry;

public ItemStateConditionHandler(Condition condition) {
super(condition);
Expand Down Expand Up @@ -74,6 +77,7 @@ public void dispose() {
itemRegistry = null;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public boolean isSatisfied(Map<String, Object> inputs) {
String itemName = (String) module.getConfiguration().get(ITEM_NAME);
Expand All @@ -92,44 +96,118 @@ public boolean isSatisfied(Map<String, Object> inputs) {
Item item = itemRegistry.getItem(itemName);
State compareState = TypeParser.parseState(item.getAcceptedDataTypes(), state);
State itemState = item.getState();
DecimalType decimalState = itemState.as(DecimalType.class);
logger.debug("ItemStateCondition '{}'checking if {} (State={}) {} {}", module.getId(), itemName, itemState,
operator, compareState);
switch (operator) {
case "=":
logger.debug("ConditionSatisfied --> {}", itemState.equals(compareState));
return itemState.equals(compareState);
case "!=":
return !itemState.equals(compareState);
case "<":
if (null != decimalState && compareState instanceof DecimalType) {
return decimalState.compareTo((DecimalType) compareState) < 0;
if (itemState instanceof QuantityType) {
QuantityType qtState = (QuantityType) itemState;
if (compareState instanceof DecimalType) {
// allow compareState without unit -> implicitly assume its the same as the one from the
// state, but warn the user
logger.warn(
"Received a QuantityType state '{}' with unit, but the condition is defined as a plain number without unit ({}), please consider adding a unit to the condition.",
qtState, state);
return qtState.compareTo(new QuantityType<>(((DecimalType) compareState).toBigDecimal(),
qtState.getUnit())) < 0;
} else if (compareState instanceof QuantityType) {
return qtState.compareTo((QuantityType) compareState) < 0;
} else {
logger.warn(
"Condition '{}' cannot be compared to the incompatible state '{}' from the item.",
state, qtState);
}
} else if (itemState instanceof DecimalType && null != compareState) {
DecimalType decimalState = compareState.as(DecimalType.class);
if (null != decimalState) {
return ((DecimalType) itemState).compareTo(decimalState) < 0;
}
}

break;
case "<=":
case "=<":
if (null != decimalState && compareState instanceof DecimalType) {
return decimalState.compareTo((DecimalType) compareState) <= 0;
if (itemState instanceof QuantityType) {
QuantityType qtState = (QuantityType) itemState;
if (compareState instanceof DecimalType) {
// allow compareState without unit -> implicitly assume its the same as the one from the
// state, but warn the user
logger.warn(
"Received a QuantityType state '{}' with unit, but the condition is defined as a plain number without unit ({}), please consider adding a unit to the condition.",
qtState, state);
return qtState.compareTo(new QuantityType<>(((DecimalType) compareState).toBigDecimal(),
qtState.getUnit())) <= 0;
} else if (compareState instanceof QuantityType) {
return qtState.compareTo((QuantityType) compareState) <= 0;
} else {
logger.warn(
"Condition '{}' cannot be compared to the incompatible state '{}' from the item.",
state, qtState);
}
} else if (itemState instanceof DecimalType && null != compareState) {
DecimalType decimalState = compareState.as(DecimalType.class);
if (null != decimalState) {
return ((DecimalType) itemState).compareTo(decimalState) <= 0;
}
}
break;
case ">":
if (null != decimalState && compareState instanceof DecimalType) {
return decimalState.compareTo((DecimalType) compareState) > 0;
if (itemState instanceof QuantityType) {
QuantityType qtState = (QuantityType) itemState;
if (compareState instanceof DecimalType) {
// allow compareState without unit -> implicitly assume its the same as the one from the
// state, but warn the user
logger.warn(
"Received a QuantityType state '{}' with unit, but the condition is defined as a plain number without unit ({}), please consider adding a unit to the condition.",
qtState, state);
return qtState.compareTo(new QuantityType<>(((DecimalType) compareState).toBigDecimal(),
qtState.getUnit())) > 0;
} else if (compareState instanceof QuantityType) {
return qtState.compareTo((QuantityType) compareState) > 0;
} else {
logger.warn(
"Condition '{}' cannot be compared to the incompatible state '{}' from the item.",
state, qtState);
}
} else if (itemState instanceof DecimalType && null != compareState) {
DecimalType decimalState = compareState.as(DecimalType.class);
if (null != decimalState) {
return ((DecimalType) itemState).compareTo(decimalState) > 0;
}
}
break;
case ">=":
case "=>":
if (null != decimalState && compareState instanceof DecimalType) {
return decimalState.compareTo((DecimalType) compareState) >= 0;
if (itemState instanceof QuantityType) {
QuantityType qtState = (QuantityType) itemState;
if (compareState instanceof DecimalType) {
// allow compareState without unit -> implicitly assume its the same as the one from the
// state, but warn the user
logger.warn(
"Received a QuantityType state '{}' with unit, but the condition is defined as a plain number without unit ({}), please consider adding a unit to the condition.",
qtState, state);
return qtState.compareTo(new QuantityType<>(((DecimalType) compareState).toBigDecimal(),
qtState.getUnit())) >= 0;
} else if (compareState instanceof QuantityType) {
return qtState.compareTo((QuantityType) compareState) >= 0;
} else {
logger.warn(
"Condition '{}' cannot be compared to the incompatible state '{}' from the item.",
state, qtState);
}
} else if (itemState instanceof DecimalType && null != compareState) {
DecimalType decimalState = compareState.as(DecimalType.class);
if (null != decimalState) {
return ((DecimalType) itemState).compareTo(decimalState) >= 0;
}
}
break;
default:
break;
}
} catch (ItemNotFoundException e) {
logger.error("Item with Name {} not found in itemRegistry", itemName);
return false;
}
return false;
}
Expand Down
Loading