2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.persistence.influxdb.internal;
15 import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_CATEGORY_NAME;
16 import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_ITEM_NAME;
17 import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_LABEL_NAME;
18 import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_TYPE_NAME;
20 import java.time.Instant;
21 import java.util.Objects;
22 import java.util.Optional;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.core.items.Item;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.UnDefType;
31 * Logic to create an InfluxDB {@link InfluxPoint} from an openHAB {@link Item}
33 * @author Joan Pujol Espinar - Initial contribution
36 public class ItemToStorePointCreator {
37 private final InfluxDBConfiguration configuration;
38 private final InfluxDBMetadataService influxDBMetadataService;
40 public ItemToStorePointCreator(InfluxDBConfiguration configuration,
41 InfluxDBMetadataService influxDBMetadataService) {
42 this.configuration = configuration;
43 this.influxDBMetadataService = influxDBMetadataService;
46 public @Nullable InfluxPoint convert(Item item, @Nullable String storeAlias) {
47 if (item.getState() instanceof UnDefType) {
51 String measurementName = calculateMeasurementName(item, storeAlias);
52 String itemName = item.getName();
53 State state = getItemState(item);
55 Object value = InfluxDBStateConvertUtils.stateToObject(state);
57 InfluxPoint.Builder pointBuilder = InfluxPoint.newBuilder(measurementName).withTime(Instant.now())
58 .withValue(value).withTag(TAG_ITEM_NAME, itemName);
60 addPointTags(item, pointBuilder);
62 return pointBuilder.build();
65 private String calculateMeasurementName(Item item, @Nullable String storeAlias) {
66 String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName();
67 name = influxDBMetadataService.getMeasurementNameOrDefault(item.getName(), name);
69 if (configuration.isReplaceUnderscore()) {
70 name = name.replace('_', '.');
76 private State getItemState(Item item) {
77 return calculateDesiredTypeConversionToStore(item)
78 .map(desiredClass -> Objects.requireNonNullElseGet(item.getStateAs(desiredClass), item::getState))
79 .orElseGet(item::getState);
82 private Optional<Class<? extends State>> calculateDesiredTypeConversionToStore(Item item) {
83 return item.getAcceptedCommandTypes().stream().filter(commandType -> commandType.isAssignableFrom(State.class))
84 .findFirst().map(commandType -> commandType.asSubclass(State.class));
87 private void addPointTags(Item item, InfluxPoint.Builder pointBuilder) {
88 if (configuration.isAddCategoryTag()) {
89 String categoryName = Objects.requireNonNullElse(item.getCategory(), "n/a");
90 pointBuilder.withTag(TAG_CATEGORY_NAME, categoryName);
93 if (configuration.isAddTypeTag()) {
94 pointBuilder.withTag(TAG_TYPE_NAME, item.getType());
97 if (configuration.isAddLabelTag()) {
98 String labelName = Objects.requireNonNullElse(item.getLabel(), "n/a");
99 pointBuilder.withTag(TAG_LABEL_NAME, labelName);
102 influxDBMetadataService.getMetaData(item.getName())
103 .ifPresent(metadata -> metadata.getConfiguration().forEach(pointBuilder::withTag));