import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.ContactItem;
import org.openhab.core.library.items.DateTimeItem;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringListType;
import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.Units;
import org.openhab.core.persistence.HistoricItem;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
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.
*/
@NonNullByDefault
public class JpaHistoricItem implements HistoricItem {
+ private static final Logger logger = LoggerFactory.getLogger(JpaHistoricItem.class);
private final String name;
private final State state;
* @return list of historic items
*/
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());
}
/**
* @param item the source reference Item
* @return historic item
*/
- public static HistoricItem fromPersistedItem(JpaPersistentItem pItem, Item item) {
+ public static @Nullable HistoricItem fromPersistedItem(JpaPersistentItem pItem, Item item) {
State state;
if (item instanceof NumberItem numberItem) {
Unit<?> unit = numberItem.getUnit();
- double value = Double.parseDouble(pItem.getValue());
- state = (unit == null) ? new DecimalType(value) : new QuantityType<>(value, unit);
+ QuantityType<?> value = QuantityType.valueOf(pItem.getValue());
+ 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) {
state = new PercentType(Integer.parseInt(pItem.getValue()));
} else if (item instanceof SwitchItem) {