From fa7db1c40ca55d323b70d58263b0a42921ace7cb Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Wed, 28 Oct 2020 00:27:54 +0100 Subject: [PATCH] [rrd4j] Correctly identify Number items with dimensions and persist them in the defined unit (#8866) Signed-off-by: Kai Kreuzer --- .../internal/RRD4jPersistenceService.java | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/bundles/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jPersistenceService.java b/bundles/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jPersistenceService.java index 019fe94a99c6..79fac15056ab 100644 --- a/bundles/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jPersistenceService.java +++ b/bundles/org.openhab.persistence.rrd4j/src/main/java/org/openhab/persistence/rrd4j/internal/RRD4jPersistenceService.java @@ -32,6 +32,9 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import javax.measure.Quantity; +import javax.measure.Unit; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.OpenHAB; @@ -39,6 +42,7 @@ import org.openhab.core.items.Item; import org.openhab.core.items.ItemNotFoundException; import org.openhab.core.items.ItemRegistry; +import org.openhab.core.items.ItemUtil; import org.openhab.core.library.CoreItemFactory; import org.openhab.core.library.items.ContactItem; import org.openhab.core.library.items.DimmerItem; @@ -49,6 +53,7 @@ import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.persistence.FilterCriteria; import org.openhab.core.persistence.FilterCriteria.Ordering; import org.openhab.core.persistence.HistoricItem; @@ -160,16 +165,38 @@ public synchronized void store(final Item item, @Nullable final String alias) { Sample sample = db.createSample(); sample.setTime(now); - DecimalType state = item.getStateAs(DecimalType.class); - if (state != null) { - double value = state.toBigDecimal().doubleValue(); + Double value = null; + + if (item instanceof NumberItem && item.getState() instanceof QuantityType) { + NumberItem nItem = (NumberItem) item; + QuantityType qState = (QuantityType) item.getState(); + Unit> unit = nItem.getUnit(); + if (unit != null) { + QuantityType convertedState = qState.toUnit(unit); + if (convertedState != null) { + value = convertedState.doubleValue(); + } else { + logger.warn( + "Failed to convert state '{}' to unit '{}'. Please check your item definition for correctness.", + qState, unit); + } + } else { + value = qState.doubleValue(); + } + } else { + DecimalType state = item.getStateAs(DecimalType.class); + if (state != null) { + value = state.toBigDecimal().doubleValue(); + } + } + if (value != null) { if (db.getDatasource(DATASOURCE_STATE).getType() == DsType.COUNTER) { // counter values must be // adjusted by stepsize value = value * db.getRrdDef().getStep(); } sample.setValue(DATASOURCE_STATE, value); sample.update(); - logger.debug("Stored '{}' with state '{}' in rrd4j database", name, state); + logger.debug("Stored '{}' with state '{}' in rrd4j database", name, value); } } catch (IllegalArgumentException e) { if (e.getMessage().contains("at least one second step is required")) { @@ -356,6 +383,7 @@ public ConsolFun getConsolidationFunction(RrdDb db) { } } + @SuppressWarnings({ "rawtypes", "unchecked" }) private State mapToState(double value, String itemName) { try { Item item = itemRegistry.getItem(itemName); @@ -366,6 +394,13 @@ private State mapToState(double value, String itemName) { } else if (item instanceof DimmerItem || item instanceof RollershutterItem) { // make sure Items that need PercentTypes instead of DecimalTypes do receive the right information return new PercentType((int) Math.round(value * 100)); + } else if (item instanceof NumberItem) { + Unit> unit = ((NumberItem) item).getUnit(); + if (unit != null) { + return new QuantityType(value, unit); + } else { + return new DecimalType(value); + } } } catch (ItemNotFoundException e) { logger.debug("Could not find item '{}' in registry", itemName); @@ -375,7 +410,7 @@ private State mapToState(double value, String itemName) { } private boolean isSupportedItemType(Item item) { - return SUPPORTED_TYPES.contains(item.getType()); + return SUPPORTED_TYPES.contains(ItemUtil.getMainItemType(item.getType())); } private static String getUserPersistenceDataFolder() {