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.*;
17 import java.time.Instant;
18 import java.util.Optional;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.core.items.Item;
23 import org.openhab.core.items.Metadata;
24 import org.openhab.core.items.MetadataKey;
25 import org.openhab.core.items.MetadataRegistry;
26 import org.openhab.core.types.State;
27 import org.openhab.core.types.UnDefType;
28 import org.openhab.persistence.influxdb.InfluxDBPersistenceService;
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 @Nullable MetadataRegistry metadataRegistry;
40 public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable MetadataRegistry metadataRegistry) {
41 this.configuration = configuration;
42 this.metadataRegistry = metadataRegistry;
45 public @Nullable InfluxPoint convert(Item item, @Nullable String storeAlias) {
46 if (item.getState() instanceof UnDefType) {
50 String measurementName = calculateMeasurementName(item, storeAlias);
51 String itemName = item.getName();
52 State state = getItemState(item);
54 Object value = InfluxDBStateConvertUtils.stateToObject(state);
56 InfluxPoint.Builder point = InfluxPoint.newBuilder(measurementName).withTime(Instant.now()).withValue(value)
57 .withTag(TAG_ITEM_NAME, itemName);
59 addPointTags(item, point);
64 private String calculateMeasurementName(Item item, @Nullable String storeAlias) {
65 String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName();
67 name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name,
70 if (configuration.isReplaceUnderscore()) {
71 name = name.replace('_', '.');
77 private State getItemState(Item item) {
79 final Optional<Class<? extends State>> desiredConversion = calculateDesiredTypeConversionToStore(item);
80 if (desiredConversion.isPresent()) {
81 State convertedState = item.getStateAs(desiredConversion.get());
82 if (convertedState != null) {
83 state = convertedState;
85 state = item.getState();
88 state = item.getState();
93 private Optional<Class<? extends State>> calculateDesiredTypeConversionToStore(Item item) {
94 return item.getAcceptedCommandTypes().stream().filter(commandType -> commandType.isAssignableFrom(State.class))
95 .findFirst().map(commandType -> commandType.asSubclass(State.class));
98 private void addPointTags(Item item, InfluxPoint.Builder point) {
99 if (configuration.isAddCategoryTag()) {
100 String categoryName = item.getCategory();
101 if (categoryName == null) {
102 categoryName = "n/a";
104 point.withTag(TAG_CATEGORY_NAME, categoryName);
107 if (configuration.isAddTypeTag()) {
108 point.withTag(TAG_TYPE_NAME, item.getType());
111 if (configuration.isAddLabelTag()) {
112 String labelName = item.getLabel();
113 if (labelName == null) {
116 point.withTag(TAG_LABEL_NAME, labelName);
119 final MetadataRegistry currentMetadataRegistry = metadataRegistry;
120 if (currentMetadataRegistry != null) {
121 MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName());
122 Metadata metadata = currentMetadataRegistry.get(key);
123 if (metadata != null) {
124 metadata.getConfiguration().forEach((tagName, tagValue) -> {
125 point.withTag(tagName, tagValue.toString());