mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[jpa] Fix restoring quantity types (#17215)
* [jpa] Fix restoring quantity types Double.parseDouble throws NumberFormatException if the persisted state includes a unit. So parse it as a QuantityType, and then apply unit conversions as necessary. Signed-off-by: Cody Cutrer <cody@cutrer.us> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
64331da0ad
commit
d528605bcf
@ -17,11 +17,13 @@ import java.time.Instant;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.measure.Unit;
|
import javax.measure.Unit;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.items.Item;
|
import org.openhab.core.items.Item;
|
||||||
import org.openhab.core.library.items.ContactItem;
|
import org.openhab.core.library.items.ContactItem;
|
||||||
import org.openhab.core.library.items.DateTimeItem;
|
import org.openhab.core.library.items.DateTimeItem;
|
||||||
@ -39,10 +41,13 @@ import org.openhab.core.library.types.PointType;
|
|||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
import org.openhab.core.library.types.StringListType;
|
import org.openhab.core.library.types.StringListType;
|
||||||
import org.openhab.core.library.types.StringType;
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
import org.openhab.core.persistence.HistoricItem;
|
import org.openhab.core.persistence.HistoricItem;
|
||||||
import org.openhab.core.types.State;
|
import org.openhab.core.types.State;
|
||||||
import org.openhab.core.types.UnDefType;
|
import org.openhab.core.types.UnDefType;
|
||||||
import org.openhab.persistence.jpa.internal.model.JpaPersistentItem;
|
import org.openhab.persistence.jpa.internal.model.JpaPersistentItem;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The historic item as returned when querying the service.
|
* The historic item as returned when querying the service.
|
||||||
@ -52,6 +57,7 @@ import org.openhab.persistence.jpa.internal.model.JpaPersistentItem;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class JpaHistoricItem implements HistoricItem {
|
public class JpaHistoricItem implements HistoricItem {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(JpaHistoricItem.class);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final State state;
|
private final State state;
|
||||||
@ -91,7 +97,8 @@ public class JpaHistoricItem implements HistoricItem {
|
|||||||
* @return list of historic items
|
* @return list of historic items
|
||||||
*/
|
*/
|
||||||
public static List<HistoricItem> fromResultList(List<JpaPersistentItem> jpaQueryResult, Item item) {
|
public static List<HistoricItem> fromResultList(List<JpaPersistentItem> jpaQueryResult, Item item) {
|
||||||
return jpaQueryResult.stream().map(pItem -> fromPersistedItem(pItem, item)).collect(Collectors.toList());
|
return jpaQueryResult.stream().map(pItem -> fromPersistedItem(pItem, item)).filter(Objects::nonNull)
|
||||||
|
.map(Objects::requireNonNull).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,12 +108,26 @@ public class JpaHistoricItem implements HistoricItem {
|
|||||||
* @param item the source reference Item
|
* @param item the source reference Item
|
||||||
* @return historic item
|
* @return historic item
|
||||||
*/
|
*/
|
||||||
public static HistoricItem fromPersistedItem(JpaPersistentItem pItem, Item item) {
|
public static @Nullable HistoricItem fromPersistedItem(JpaPersistentItem pItem, Item item) {
|
||||||
State state;
|
State state;
|
||||||
if (item instanceof NumberItem numberItem) {
|
if (item instanceof NumberItem numberItem) {
|
||||||
Unit<?> unit = numberItem.getUnit();
|
Unit<?> unit = numberItem.getUnit();
|
||||||
double value = Double.parseDouble(pItem.getValue());
|
QuantityType<?> value = QuantityType.valueOf(pItem.getValue());
|
||||||
state = (unit == null) ? new DecimalType(value) : new QuantityType<>(value, unit);
|
if (unit == null) {
|
||||||
|
// Item has no unit; drop any persisted unit
|
||||||
|
state = Objects.requireNonNull(value.as(DecimalType.class));
|
||||||
|
} else if (value.getUnit() == Units.ONE) {
|
||||||
|
// No persisted unit; assume the item's unit
|
||||||
|
state = new QuantityType<>(value.toBigDecimal(), unit);
|
||||||
|
} else {
|
||||||
|
// Ensure we return in the item's unit
|
||||||
|
state = value.toUnit(unit);
|
||||||
|
if (state == null) {
|
||||||
|
logger.warn("Persisted state {} for item {} is incompatible with item's unit {}; ignoring", value,
|
||||||
|
item.getName(), unit);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (item instanceof DimmerItem) {
|
} else if (item instanceof DimmerItem) {
|
||||||
state = new PercentType(Integer.parseInt(pItem.getValue()));
|
state = new PercentType(Integer.parseInt(pItem.getValue()));
|
||||||
} else if (item instanceof SwitchItem) {
|
} else if (item instanceof SwitchItem) {
|
||||||
|
Loading…
Reference in New Issue
Block a user