From ac4178237e00596d2d2030670be8c259f85d0ad8 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sun, 24 Jan 2021 17:10:02 +0100 Subject: [PATCH 01/16] Add option for using metadata value as measurement name Signed-off-by: Johannes Ott --- .../influxdb/internal/InfluxDBConfiguration.java | 7 +++++++ .../influxdb/internal/ItemToStorePointCreator.java | 14 ++++++++++++++ .../src/main/resources/OH-INF/config/config.xml | 14 ++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java index 933d657e40efc..d1e9fcdde2ae3 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java @@ -36,6 +36,7 @@ public class InfluxDBConfiguration { public static final String RETENTION_POLICY_PARAM = "retentionPolicy"; public static final String VERSION_PARAM = "version"; public static final String REPLACE_UNDERSCORE_PARAM = "replaceUnderscore"; + public static final String META_MEASUREMENT_NAME = "metaMeasurementName"; public static final String ADD_CATEGORY_TAG_PARAM = "addCategoryTag"; public static final String ADD_LABEL_TAG_PARAM = "addLabelTag"; public static final String ADD_TYPE_TAG_PARAM = "addTypeTag"; @@ -49,6 +50,7 @@ public class InfluxDBConfiguration { private final String retentionPolicy; private final InfluxDBVersion version; + private final boolean metaMeasurementName; private final boolean replaceUnderscore; private final boolean addCategoryTag; private final boolean addTypeTag; @@ -63,6 +65,7 @@ public InfluxDBConfiguration(Map config) { retentionPolicy = (String) config.getOrDefault(RETENTION_POLICY_PARAM, "autogen"); version = parseInfluxVersion(config.getOrDefault(VERSION_PARAM, InfluxDBVersion.V1.name())); + metaMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); replaceUnderscore = getConfigBooleanValue(config, REPLACE_UNDERSCORE_PARAM, false); addCategoryTag = getConfigBooleanValue(config, ADD_CATEGORY_TAG_PARAM, false); addLabelTag = getConfigBooleanValue(config, ADD_LABEL_TAG_PARAM, false); @@ -144,6 +147,10 @@ public boolean isReplaceUnderscore() { return replaceUnderscore; } + public boolean isMetaMeasurementName() { + return metaMeasurementName; + } + public boolean isAddCategoryTag() { return addCategoryTag; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index f66b2df5a919c..b6273c01fc202 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,6 +64,20 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); + if (configuration.isMetaMeasurementName()) { + final MetadataRegistry currentMetadataRegistry = metadataRegistry; + if (currentMetadataRegistry != null) { + MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); + Metadata metadata = currentMetadataRegistry.get(key); + if (metadata != null) { + String metaName = metadata.getValue(); + if (!metaName.isBlank()) { + name = metaName; + } + } + } + } + if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml index 5c44cbc882f89..4e8da2edee321 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml @@ -1,8 +1,6 @@ - @@ -81,6 +79,14 @@ false + + + Should the measurement name set by metadata influxdb value if exists? If no metadata is set, item name + is used. + + false + + Should the category of the item be included as tag "category"? If no category is set, "n/a" is From 2558e0e324d68a091880d32337c0e457a7d184db Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Mon, 25 Jan 2021 19:12:37 +0100 Subject: [PATCH 02/16] Rename new configuration param to useMetaMeasurementName. Modify query builder to find data in correct measurement. Add tests for new feature. Signed-off-by: Johannes Ott --- .../influxdb/InfluxDBPersistenceService.java | 27 +++++---- .../internal/InfluxDBConfiguration.java | 10 ++-- .../internal/ItemToStorePointCreator.java | 2 +- .../influxdb/internal/RepositoryFactory.java | 13 ++-- ...Influx1FilterCriteriaQueryCreatorImpl.java | 58 ++++++++++++++++-- ...Influx2FilterCriteriaQueryCreatorImpl.java | 49 ++++++++++++++- .../main/resources/OH-INF/config/config.xml | 8 ++- ...luxFilterCriteriaQueryCreatorImplTest.java | 60 ++++++++++++++++++- .../internal/ItemToStorePointCreatorTest.java | 28 +++++++++ 9 files changed, 219 insertions(+), 36 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/InfluxDBPersistenceService.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/InfluxDBPersistenceService.java index 6edaff7a859b5..7828acd954144 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/InfluxDBPersistenceService.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/InfluxDBPersistenceService.java @@ -54,20 +54,23 @@ import org.slf4j.LoggerFactory; /** - * This is the implementation of the InfluxDB {@link PersistenceService}. It persists item values - * using the InfluxDB time series database. The states ( - * {@link State}) of an {@link Item} are persisted by default in a time series with names equal to the name of - * the item. + * This is the implementation of the InfluxDB {@link PersistenceService}. It + * persists item values using the InfluxDB time + * series database. The states ( {@link State}) of an {@link Item} are persisted + * by default in a time series with names equal to the name of the item. * - * This addon supports 1.X and 2.X versions, as two versions are incompatible and use different drivers the - * specific code for each version is accessed by {@link InfluxDBRepository} and {@link FilterCriteriaQueryCreator} - * interfaces and specific implementation reside in {@link org.openhab.persistence.influxdb.internal.influx1} and + * This addon supports 1.X and 2.X versions, as two versions are incompatible + * and use different drivers the specific code for each version is accessed by + * {@link InfluxDBRepository} and {@link FilterCriteriaQueryCreator} interfaces + * and specific implementation reside in + * {@link org.openhab.persistence.influxdb.internal.influx1} and * {@link org.openhab.persistence.influxdb.internal.influx2} packages * - * @author Theo Weiss - Initial contribution, rewrite of org.openhab.persistence.influxdb - * @author Joan Pujol Espinar - Addon rewrite refactoring code and adding support for InfluxDB 2.0. Some tag code is - * based - * from not integrated branch from Dominik Vorreiter + * @author Theo Weiss - Initial contribution, rewrite of + * org.openhab.persistence.influxdb + * @author Joan Pujol Espinar - Addon rewrite refactoring code and adding + * support for InfluxDB 2.0. Some tag code is based from not integrated + * branch from Dominik Vorreiter */ @NonNullByDefault @Component(service = { PersistenceService.class, @@ -222,7 +225,7 @@ public Iterable query(FilterCriteria filter) { filter.getItemName(), filter.getOrdering().toString(), filter.getState(), filter.getOperator(), filter.getBeginDate(), filter.getEndDate(), filter.getPageSize(), filter.getPageNumber()); - String query = RepositoryFactory.createQueryCreator(configuration).createQuery(filter, + String query = RepositoryFactory.createQueryCreator(configuration, metadataRegistry).createQuery(filter, configuration.getRetentionPolicy()); logger.trace("Query {}", query); List results = influxDBRepository.query(query); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java index d1e9fcdde2ae3..d3c19de96a951 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java @@ -36,7 +36,7 @@ public class InfluxDBConfiguration { public static final String RETENTION_POLICY_PARAM = "retentionPolicy"; public static final String VERSION_PARAM = "version"; public static final String REPLACE_UNDERSCORE_PARAM = "replaceUnderscore"; - public static final String META_MEASUREMENT_NAME = "metaMeasurementName"; + public static final String META_MEASUREMENT_NAME = "useMetaMeasurementName"; public static final String ADD_CATEGORY_TAG_PARAM = "addCategoryTag"; public static final String ADD_LABEL_TAG_PARAM = "addLabelTag"; public static final String ADD_TYPE_TAG_PARAM = "addTypeTag"; @@ -50,7 +50,7 @@ public class InfluxDBConfiguration { private final String retentionPolicy; private final InfluxDBVersion version; - private final boolean metaMeasurementName; + private final boolean useMetaMeasurementName; private final boolean replaceUnderscore; private final boolean addCategoryTag; private final boolean addTypeTag; @@ -65,7 +65,7 @@ public InfluxDBConfiguration(Map config) { retentionPolicy = (String) config.getOrDefault(RETENTION_POLICY_PARAM, "autogen"); version = parseInfluxVersion(config.getOrDefault(VERSION_PARAM, InfluxDBVersion.V1.name())); - metaMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); + useMetaMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); replaceUnderscore = getConfigBooleanValue(config, REPLACE_UNDERSCORE_PARAM, false); addCategoryTag = getConfigBooleanValue(config, ADD_CATEGORY_TAG_PARAM, false); addLabelTag = getConfigBooleanValue(config, ADD_LABEL_TAG_PARAM, false); @@ -147,8 +147,8 @@ public boolean isReplaceUnderscore() { return replaceUnderscore; } - public boolean isMetaMeasurementName() { - return metaMeasurementName; + public boolean isUseMetaMeasurementName() { + return useMetaMeasurementName; } public boolean isAddCategoryTag() { diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index b6273c01fc202..a8243df1322e5 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,7 +64,7 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); - if (configuration.isMetaMeasurementName()) { + if (configuration.isUseMetaMeasurementName()) { final MetadataRegistry currentMetadataRegistry = metadataRegistry; if (currentMetadataRegistry != null) { MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/RepositoryFactory.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/RepositoryFactory.java index 7c083a31eb621..5256bbe6bdfd6 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/RepositoryFactory.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/RepositoryFactory.java @@ -13,14 +13,16 @@ package org.openhab.persistence.influxdb.internal; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.items.MetadataRegistry; import org.openhab.persistence.influxdb.internal.influx1.Influx1FilterCriteriaQueryCreatorImpl; import org.openhab.persistence.influxdb.internal.influx1.InfluxDB1RepositoryImpl; import org.openhab.persistence.influxdb.internal.influx2.Influx2FilterCriteriaQueryCreatorImpl; import org.openhab.persistence.influxdb.internal.influx2.InfluxDB2RepositoryImpl; /** - * Factory that returns {@link InfluxDBRepository} and {@link FilterCriteriaQueryCreator} implementations - * depending on InfluxDB version + * Factory that returns {@link InfluxDBRepository} and + * {@link FilterCriteriaQueryCreator} implementations depending on InfluxDB + * version * * @author Joan Pujol Espinar - Initial contribution */ @@ -38,12 +40,13 @@ public static InfluxDBRepository createRepository(InfluxDBConfiguration influxDB } } - public static FilterCriteriaQueryCreator createQueryCreator(InfluxDBConfiguration influxDBConfiguration) { + public static FilterCriteriaQueryCreator createQueryCreator(InfluxDBConfiguration influxDBConfiguration, + MetadataRegistry metadataRegistry) { switch (influxDBConfiguration.getVersion()) { case V1: - return new Influx1FilterCriteriaQueryCreatorImpl(); + return new Influx1FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); case V2: - return new Influx2FilterCriteriaQueryCreatorImpl(); + return new Influx2FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); default: throw new UnnexpectedConditionException("Not expected version " + influxDBConfiguration.getVersion()); } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 0785ca08730f2..dfc62237af197 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -17,14 +17,20 @@ import static org.openhab.persistence.influxdb.internal.InfluxDBStateConvertUtils.stateToObject; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.influxdb.dto.Query; import org.influxdb.querybuilder.Appender; import org.influxdb.querybuilder.BuiltQuery; import org.influxdb.querybuilder.Select; import org.influxdb.querybuilder.Where; import org.influxdb.querybuilder.clauses.SimpleClause; +import org.openhab.core.items.Metadata; +import org.openhab.core.items.MetadataKey; +import org.openhab.core.items.MetadataRegistry; import org.openhab.core.persistence.FilterCriteria; +import org.openhab.persistence.influxdb.InfluxDBPersistenceService; import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator; +import org.openhab.persistence.influxdb.internal.InfluxDBConfiguration; import org.openhab.persistence.influxdb.internal.InfluxDBVersion; /** @@ -35,20 +41,32 @@ @NonNullByDefault public class Influx1FilterCriteriaQueryCreatorImpl implements FilterCriteriaQueryCreator { + private InfluxDBConfiguration configuration; + private MetadataRegistry metadataRegistry; + + public Influx1FilterCriteriaQueryCreatorImpl(InfluxDBConfiguration configuration, + MetadataRegistry metadataRegistry) { + this.configuration = configuration; + this.metadataRegistry = metadataRegistry; + } + @Override public String createQuery(FilterCriteria criteria, String retentionPolicy) { final String tableName; - boolean hasCriteriaName = criteria.getItemName() != null; - if (hasCriteriaName) { - tableName = criteria.getItemName(); - } else { - tableName = "/.*/"; - } + final String itemName = criteria.getItemName(); + boolean hasCriteriaName = itemName != null; + + tableName = calculateTableName(itemName); Select select = select(COLUMN_VALUE_NAME_V1).fromRaw(null, fullQualifiedTableName(retentionPolicy, tableName, hasCriteriaName)); Where where = select.where(); + + if (configuration.isUseMetaMeasurementName() && hasCriteriaName) { + where = where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName)); + } + if (criteria.getBeginDate() != null) { where = where.and( BuiltQuery.QueryBuilder.gte(COLUMN_TIME_NAME_V1, criteria.getBeginDate().toInstant().toString())); @@ -82,6 +100,34 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { return query.getCommand(); } + private String calculateTableName(@Nullable String itemName) { + if (itemName == null) { + return "/.*/"; + } + + String name = itemName; + + if (configuration.isUseMetaMeasurementName()) { + final MetadataRegistry currentMetadataRegistry = metadataRegistry; + if (currentMetadataRegistry != null) { + MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); + Metadata metadata = currentMetadataRegistry.get(key); + if (metadata != null) { + String metaName = metadata.getValue(); + if (!metaName.isBlank()) { + name = metaName; + } + } + } + } + + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + + return name; + } + private String fullQualifiedTableName(String retentionPolicy, String tableName, boolean escapeTableName) { StringBuilder sb = new StringBuilder(); Appender.appendName(retentionPolicy, sb); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index 61d7a5e4d4a19..f55b518a0b808 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -13,14 +13,21 @@ package org.openhab.persistence.influxdb.internal.influx2; import static com.influxdb.query.dsl.functions.restriction.Restrictions.measurement; +import static com.influxdb.query.dsl.functions.restriction.Restrictions.tag; import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.*; import static org.openhab.persistence.influxdb.internal.InfluxDBStateConvertUtils.stateToObject; import java.time.temporal.ChronoUnit; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.items.Metadata; +import org.openhab.core.items.MetadataKey; +import org.openhab.core.items.MetadataRegistry; import org.openhab.core.persistence.FilterCriteria; +import org.openhab.persistence.influxdb.InfluxDBPersistenceService; import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator; +import org.openhab.persistence.influxdb.internal.InfluxDBConfiguration; import org.openhab.persistence.influxdb.internal.InfluxDBVersion; import com.influxdb.query.dsl.Flux; @@ -34,6 +41,16 @@ */ @NonNullByDefault public class Influx2FilterCriteriaQueryCreatorImpl implements FilterCriteriaQueryCreator { + + private InfluxDBConfiguration configuration; + private MetadataRegistry metadataRegistry; + + public Influx2FilterCriteriaQueryCreatorImpl(InfluxDBConfiguration configuration, + MetadataRegistry metadataRegistry) { + this.configuration = configuration; + this.metadataRegistry = metadataRegistry; + } + @Override public String createQuery(FilterCriteria criteria, String retentionPolicy) { Flux flux = Flux.from(retentionPolicy); @@ -49,8 +66,12 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { } flux = range; - if (criteria.getItemName() != null) { - flux = flux.filter(measurement().equal(criteria.getItemName())); + String itemName = criteria.getItemName(); + if (itemName != null) { + flux = flux.filter(measurement().equal(calculateMeasurementName(itemName))); + if (configuration.isUseMetaMeasurementName()) { + flux = flux.filter(tag("item").equal(itemName)); + } } if (criteria.getState() != null && criteria.getOperator() != null) { @@ -72,4 +93,28 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { return flux.toString(); } + + private String calculateMeasurementName(@Nullable String itemName) { + String name = itemName; + + if (configuration.isUseMetaMeasurementName()) { + final MetadataRegistry currentMetadataRegistry = metadataRegistry; + if (currentMetadataRegistry != null) { + MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); + Metadata metadata = currentMetadataRegistry.get(key); + if (metadata != null) { + String metaName = metadata.getValue(); + if (!metaName.isBlank()) { + name = metaName; + } + } + } + } + + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + + return name; + } } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml index 4e8da2edee321..00bfd750eda49 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml @@ -1,6 +1,8 @@ - @@ -79,7 +81,7 @@ false - + Should the measurement name set by metadata influxdb value if exists? If no metadata is set, item name is used. diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java index b365875bb98df..bcf8d3ba55838 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java @@ -14,25 +14,35 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.when; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.util.Map; import org.eclipse.jdt.annotation.DefaultLocation; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openhab.core.items.Metadata; +import org.openhab.core.items.MetadataKey; +import org.openhab.core.items.MetadataRegistry; import org.openhab.core.library.types.PercentType; import org.openhab.core.persistence.FilterCriteria; +import org.openhab.persistence.influxdb.InfluxDBPersistenceService; import org.openhab.persistence.influxdb.internal.influx1.Influx1FilterCriteriaQueryCreatorImpl; import org.openhab.persistence.influxdb.internal.influx2.Influx2FilterCriteriaQueryCreatorImpl; /** * @author Joan Pujol Espinar - Initial contribution */ +@ExtendWith(MockitoExtension.class) @NonNullByDefault({ DefaultLocation.RETURN_TYPE, DefaultLocation.PARAMETER }) public class InfluxFilterCriteriaQueryCreatorImplTest { private static final String RETENTION_POLICY = "origin"; @@ -41,19 +51,26 @@ public class InfluxFilterCriteriaQueryCreatorImplTest { private static final DateTimeFormatter INFLUX2_DATE_FORMATTER = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnnnnn'Z'").withZone(ZoneId.of("UTC")); + private @Mock InfluxDBConfiguration influxDBConfiguration; + private @Mock MetadataRegistry metadataRegistry; + private Influx1FilterCriteriaQueryCreatorImpl instanceV1; private Influx2FilterCriteriaQueryCreatorImpl instanceV2; @BeforeEach public void before() { - instanceV1 = new Influx1FilterCriteriaQueryCreatorImpl(); - instanceV2 = new Influx2FilterCriteriaQueryCreatorImpl(); + when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); + + instanceV1 = new Influx1FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); + instanceV2 = new Influx2FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); } @AfterEach public void after() { instanceV1 = null; instanceV2 = null; + influxDBConfiguration = null; + metadataRegistry = null; } @Test @@ -68,6 +85,45 @@ public void testSimpleItemQueryWithoutParams() { + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); } + @Test + public void testMeasurementNameFromMetadata() { + FilterCriteria criteria = createBaseCriteria(); + MetadataKey metadataKey = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, "sampleItem"); + + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); + + String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem;")); + + String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); + + when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(true); + + queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV1, equalTo("SELECT value FROM origin.measurementName WHERE item = 'sampleItem';")); + + queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV2, + equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + + "|> filter(fn: (r) => r[\"_measurement\"] == \"measurementName\")\n\t" + + "|> filter(fn: (r) => r[\"item\"] == \"sampleItem\")")); + + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2"))); + + queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem WHERE item = 'sampleItem';")); + + queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV2, + equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")\n\t" + + "|> filter(fn: (r) => r[\"item\"] == \"sampleItem\")")); + } + @Test public void testEscapeSimpleItem() { FilterCriteria criteria = createBaseCriteria("sample.Item"); diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java index 544da5c95ea16..81c401d58da7d 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java @@ -54,6 +54,7 @@ public void before() { when(influxDBConfiguration.isAddLabelTag()).thenReturn(false); when(influxDBConfiguration.isAddTypeTag()).thenReturn(false); when(influxDBConfiguration.isReplaceUnderscore()).thenReturn(false); + when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); instance = new ItemToStorePointCreator(influxDBConfiguration, metadataRegistry); } @@ -140,4 +141,31 @@ public void shouldStoreMetadataAsTagsIfProvided() { assertThat(point.getTags(), hasEntry("key1", "val1")); assertThat(point.getTags(), hasEntry("key2", "val2")); } + + @Test + public void shouldUseMeasurementNameFromMetadataIfConfigured() { + NumberItem item = ItemTestHelper.createNumberItem("myitem", 5); + MetadataKey metadataKey = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); + + InfluxPoint point = instance.convert(item, null); + assertThat(point.getMeasurementName(), equalTo(item.getName())); + + when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(true); + + point = instance.convert(item, null); + assertThat(point.getMeasurementName(), equalTo(item.getName())); + assertThat(point.getTags(), hasEntry("item", "myitem")); + + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); + + point = instance.convert(item, null); + assertThat(point.getMeasurementName(), equalTo("measurementName")); + assertThat(point.getTags(), hasEntry("item", "myitem")); + + when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); + + point = instance.convert(item, null); + assertThat(point.getMeasurementName(), equalTo(item.getName())); + } } From 15865b550b130105c0699fa0ba18b89f0e53f103 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Mon, 25 Jan 2021 19:32:58 +0100 Subject: [PATCH 03/16] Rename configuration parameter Signed-off-by: Johannes Ott --- .../influxdb/internal/InfluxDBConfiguration.java | 10 +++++----- .../influxdb/internal/ItemToStorePointCreator.java | 2 +- .../influx1/Influx1FilterCriteriaQueryCreatorImpl.java | 4 ++-- .../influx2/Influx2FilterCriteriaQueryCreatorImpl.java | 4 ++-- .../src/main/resources/OH-INF/config/config.xml | 6 +++--- .../InfluxFilterCriteriaQueryCreatorImplTest.java | 4 ++-- .../influxdb/internal/ItemToStorePointCreatorTest.java | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java index d3c19de96a951..5e00750ac1cd9 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java @@ -36,7 +36,7 @@ public class InfluxDBConfiguration { public static final String RETENTION_POLICY_PARAM = "retentionPolicy"; public static final String VERSION_PARAM = "version"; public static final String REPLACE_UNDERSCORE_PARAM = "replaceUnderscore"; - public static final String META_MEASUREMENT_NAME = "useMetaMeasurementName"; + public static final String META_MEASUREMENT_NAME = "useMetadataMeasurementName"; public static final String ADD_CATEGORY_TAG_PARAM = "addCategoryTag"; public static final String ADD_LABEL_TAG_PARAM = "addLabelTag"; public static final String ADD_TYPE_TAG_PARAM = "addTypeTag"; @@ -50,7 +50,7 @@ public class InfluxDBConfiguration { private final String retentionPolicy; private final InfluxDBVersion version; - private final boolean useMetaMeasurementName; + private final boolean useMetadataMeasurementName; private final boolean replaceUnderscore; private final boolean addCategoryTag; private final boolean addTypeTag; @@ -65,7 +65,7 @@ public InfluxDBConfiguration(Map config) { retentionPolicy = (String) config.getOrDefault(RETENTION_POLICY_PARAM, "autogen"); version = parseInfluxVersion(config.getOrDefault(VERSION_PARAM, InfluxDBVersion.V1.name())); - useMetaMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); + useMetadataMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); replaceUnderscore = getConfigBooleanValue(config, REPLACE_UNDERSCORE_PARAM, false); addCategoryTag = getConfigBooleanValue(config, ADD_CATEGORY_TAG_PARAM, false); addLabelTag = getConfigBooleanValue(config, ADD_LABEL_TAG_PARAM, false); @@ -147,8 +147,8 @@ public boolean isReplaceUnderscore() { return replaceUnderscore; } - public boolean isUseMetaMeasurementName() { - return useMetaMeasurementName; + public boolean isUseMetadataMeasurementName() { + return useMetadataMeasurementName; } public boolean isAddCategoryTag() { diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index a8243df1322e5..a78d0967365f9 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,7 +64,7 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); - if (configuration.isUseMetaMeasurementName()) { + if (configuration.isUseMetadataMeasurementName()) { final MetadataRegistry currentMetadataRegistry = metadataRegistry; if (currentMetadataRegistry != null) { MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index dfc62237af197..336ed0b251a46 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -63,7 +63,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { Where where = select.where(); - if (configuration.isUseMetaMeasurementName() && hasCriteriaName) { + if (configuration.isUseMetadataMeasurementName() && hasCriteriaName) { where = where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName)); } @@ -107,7 +107,7 @@ private String calculateTableName(@Nullable String itemName) { String name = itemName; - if (configuration.isUseMetaMeasurementName()) { + if (configuration.isUseMetadataMeasurementName()) { final MetadataRegistry currentMetadataRegistry = metadataRegistry; if (currentMetadataRegistry != null) { MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index f55b518a0b808..deb9a37cfb8de 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -69,7 +69,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { String itemName = criteria.getItemName(); if (itemName != null) { flux = flux.filter(measurement().equal(calculateMeasurementName(itemName))); - if (configuration.isUseMetaMeasurementName()) { + if (configuration.isUseMetadataMeasurementName()) { flux = flux.filter(tag("item").equal(itemName)); } } @@ -97,7 +97,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { private String calculateMeasurementName(@Nullable String itemName) { String name = itemName; - if (configuration.isUseMetaMeasurementName()) { + if (configuration.isUseMetadataMeasurementName()) { final MetadataRegistry currentMetadataRegistry = metadataRegistry; if (currentMetadataRegistry != null) { MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml index 00bfd750eda49..8b7f4d4b95e10 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml @@ -81,10 +81,10 @@ false - + - Should the measurement name set by metadata influxdb value if exists? If no metadata is set, item name - is used. + If true uses metadata from item influxdb metadata value as name for measurement instead of item name. If + metadata value is not set item name is used again. false diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java index bcf8d3ba55838..50882978b3397 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java @@ -59,7 +59,7 @@ public class InfluxFilterCriteriaQueryCreatorImplTest { @BeforeEach public void before() { - when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); + when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); instanceV1 = new Influx1FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); instanceV2 = new Influx2FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); @@ -100,7 +100,7 @@ public void testMeasurementNameFromMetadata() { assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); - when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(true); + when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(true); queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); assertThat(queryV1, equalTo("SELECT value FROM origin.measurementName WHERE item = 'sampleItem';")); diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java index 81c401d58da7d..042d44065b6a1 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java @@ -54,7 +54,7 @@ public void before() { when(influxDBConfiguration.isAddLabelTag()).thenReturn(false); when(influxDBConfiguration.isAddTypeTag()).thenReturn(false); when(influxDBConfiguration.isReplaceUnderscore()).thenReturn(false); - when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); + when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); instance = new ItemToStorePointCreator(influxDBConfiguration, metadataRegistry); } @@ -150,7 +150,7 @@ public void shouldUseMeasurementNameFromMetadataIfConfigured() { InfluxPoint point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); - when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(true); + when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(true); point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); @@ -163,7 +163,7 @@ public void shouldUseMeasurementNameFromMetadataIfConfigured() { assertThat(point.getMeasurementName(), equalTo("measurementName")); assertThat(point.getTags(), hasEntry("item", "myitem")); - when(influxDBConfiguration.isUseMetaMeasurementName()).thenReturn(false); + when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); From a13790e2b77330eca3d02ac9c80e59551f079af7 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Wed, 3 Feb 2021 14:05:49 +0100 Subject: [PATCH 04/16] Refactor calculation of Metadata name method Signed-off-by: Johannes Ott --- .../internal/InfluxDBMetadataUtils.java | 59 +++++++++++++++++++ .../internal/ItemToStorePointCreator.java | 19 +----- ...Influx1FilterCriteriaQueryCreatorImpl.java | 23 +------- ...Influx2FilterCriteriaQueryCreatorImpl.java | 23 +------- 4 files changed, 67 insertions(+), 57 deletions(-) create mode 100644 bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java new file mode 100644 index 0000000000000..787f0064f16e8 --- /dev/null +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.persistence.influxdb.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.items.Metadata; +import org.openhab.core.items.MetadataKey; +import org.openhab.core.items.MetadataRegistry; +import org.openhab.persistence.influxdb.InfluxDBPersistenceService; + +/** + * Logic to use items metadata from an openHAB {@link Item} + * + * @author Johannes Ott - Initial contribution + */ +@NonNullByDefault +public class InfluxDBMetadataUtils { + + private InfluxDBMetadataUtils() { + } + + public static String calculateMeasurementNameFromMetadata(InfluxDBConfiguration configuration, + final @Nullable MetadataRegistry currentMetadataRegistry, String name, @Nullable String itemName) { + + if (itemName == null || currentMetadataRegistry == null) { + return name; + } + + if (configuration.isUseMetadataMeasurementName()) { + + MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); + Metadata metadata = currentMetadataRegistry.get(key); + if (metadata != null) { + String metaName = metadata.getValue(); + if (!metaName.isBlank()) { + name = metaName; + } + } + + } + + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + + return name; + } +} diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index a78d0967365f9..48459032408dd 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,23 +64,8 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); - if (configuration.isUseMetadataMeasurementName()) { - final MetadataRegistry currentMetadataRegistry = metadataRegistry; - if (currentMetadataRegistry != null) { - MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); - Metadata metadata = currentMetadataRegistry.get(key); - if (metadata != null) { - String metaName = metadata.getValue(); - if (!metaName.isBlank()) { - name = metaName; - } - } - } - } - - if (configuration.isReplaceUnderscore()) { - name = name.replace('_', '.'); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, + item.getName()); return name; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 336ed0b251a46..3e4431ea3da17 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -24,13 +24,11 @@ import org.influxdb.querybuilder.Select; import org.influxdb.querybuilder.Where; import org.influxdb.querybuilder.clauses.SimpleClause; -import org.openhab.core.items.Metadata; -import org.openhab.core.items.MetadataKey; import org.openhab.core.items.MetadataRegistry; import org.openhab.core.persistence.FilterCriteria; -import org.openhab.persistence.influxdb.InfluxDBPersistenceService; import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator; import org.openhab.persistence.influxdb.internal.InfluxDBConfiguration; +import org.openhab.persistence.influxdb.internal.InfluxDBMetadataUtils; import org.openhab.persistence.influxdb.internal.InfluxDBVersion; /** @@ -107,23 +105,8 @@ private String calculateTableName(@Nullable String itemName) { String name = itemName; - if (configuration.isUseMetadataMeasurementName()) { - final MetadataRegistry currentMetadataRegistry = metadataRegistry; - if (currentMetadataRegistry != null) { - MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); - Metadata metadata = currentMetadataRegistry.get(key); - if (metadata != null) { - String metaName = metadata.getValue(); - if (!metaName.isBlank()) { - name = metaName; - } - } - } - } - - if (configuration.isReplaceUnderscore()) { - name = name.replace('_', '.'); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, + itemName); return name; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index deb9a37cfb8de..7f1e933a83b37 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -21,13 +21,11 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.items.Metadata; -import org.openhab.core.items.MetadataKey; import org.openhab.core.items.MetadataRegistry; import org.openhab.core.persistence.FilterCriteria; -import org.openhab.persistence.influxdb.InfluxDBPersistenceService; import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator; import org.openhab.persistence.influxdb.internal.InfluxDBConfiguration; +import org.openhab.persistence.influxdb.internal.InfluxDBMetadataUtils; import org.openhab.persistence.influxdb.internal.InfluxDBVersion; import com.influxdb.query.dsl.Flux; @@ -97,23 +95,8 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { private String calculateMeasurementName(@Nullable String itemName) { String name = itemName; - if (configuration.isUseMetadataMeasurementName()) { - final MetadataRegistry currentMetadataRegistry = metadataRegistry; - if (currentMetadataRegistry != null) { - MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); - Metadata metadata = currentMetadataRegistry.get(key); - if (metadata != null) { - String metaName = metadata.getValue(); - if (!metaName.isBlank()) { - name = metaName; - } - } - } - } - - if (configuration.isReplaceUnderscore()) { - name = name.replace('_', '.'); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, + itemName); return name; } From 76d710234f97b70673d738e2288000ec3a529f27 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Wed, 3 Feb 2021 14:21:47 +0100 Subject: [PATCH 05/16] Moved configuration isReplaceUnderscore back to original place Signed-off-by: Johannes Ott --- .../persistence/influxdb/internal/InfluxDBMetadataUtils.java | 4 ---- .../influxdb/internal/ItemToStorePointCreator.java | 4 ++++ .../influx1/Influx1FilterCriteriaQueryCreatorImpl.java | 4 ++++ .../influx2/Influx2FilterCriteriaQueryCreatorImpl.java | 4 ++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java index 787f0064f16e8..a353129cc1d65 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java @@ -50,10 +50,6 @@ public static String calculateMeasurementNameFromMetadata(InfluxDBConfiguration } - if (configuration.isReplaceUnderscore()) { - name = name.replace('_', '.'); - } - return name; } } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index 48459032408dd..46040fa6a4de9 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -67,6 +67,10 @@ private String calculateMeasurementName(Item item, @Nullable String storeAlias) name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, item.getName()); + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + return name; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 3e4431ea3da17..42aadc748bb2d 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -108,6 +108,10 @@ private String calculateTableName(@Nullable String itemName) { name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, itemName); + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + return name; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index 7f1e933a83b37..9c810d07adaf2 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -98,6 +98,10 @@ private String calculateMeasurementName(@Nullable String itemName) { name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, itemName); + if (configuration.isReplaceUnderscore()) { + name = name.replace('_', '.'); + } + return name; } } From b6043911bcc1b93c977f40dd771d9bd3a41ddd2c Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Wed, 3 Feb 2021 15:05:23 +0100 Subject: [PATCH 06/16] Removed unneccessary Nullable annotation Signed-off-by: Johannes Ott --- .../influx2/Influx2FilterCriteriaQueryCreatorImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index 9c810d07adaf2..afdaa6d1c4a2b 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -20,7 +20,6 @@ import java.time.temporal.ChronoUnit; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.items.MetadataRegistry; import org.openhab.core.persistence.FilterCriteria; import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator; @@ -92,7 +91,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { return flux.toString(); } - private String calculateMeasurementName(@Nullable String itemName) { + private String calculateMeasurementName(String itemName) { String name = itemName; name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, From 86c2f75640f8abea62527303de2bf073f49586f3 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Tue, 9 Feb 2021 13:47:32 +0100 Subject: [PATCH 07/16] Call calculation method only if configuration enabled Signed-off-by: Johannes Ott --- .../internal/InfluxDBMetadataUtils.java | 18 +++++++----------- .../internal/ItemToStorePointCreator.java | 6 ++++-- .../Influx1FilterCriteriaQueryCreatorImpl.java | 6 ++++-- .../Influx2FilterCriteriaQueryCreatorImpl.java | 6 ++++-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java index a353129cc1d65..3128592329ed5 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBMetadataUtils.java @@ -30,24 +30,20 @@ public class InfluxDBMetadataUtils { private InfluxDBMetadataUtils() { } - public static String calculateMeasurementNameFromMetadata(InfluxDBConfiguration configuration, + public static String calculateMeasurementNameFromMetadataIfPresent( final @Nullable MetadataRegistry currentMetadataRegistry, String name, @Nullable String itemName) { if (itemName == null || currentMetadataRegistry == null) { return name; } - if (configuration.isUseMetadataMeasurementName()) { - - MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); - Metadata metadata = currentMetadataRegistry.get(key); - if (metadata != null) { - String metaName = metadata.getValue(); - if (!metaName.isBlank()) { - name = metaName; - } + MetadataKey key = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, itemName); + Metadata metadata = currentMetadataRegistry.get(key); + if (metadata != null) { + String metaName = metadata.getValue(); + if (!metaName.isBlank()) { + name = metaName; } - } return name; diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index 46040fa6a4de9..70f22127f2405 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,8 +64,10 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, - item.getName()); + if (configuration.isUseMetadataMeasurementName()) { + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, + item.getName()); + } if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 42aadc748bb2d..fe3f15cc4a5ee 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -105,8 +105,10 @@ private String calculateTableName(@Nullable String itemName) { String name = itemName; - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, - itemName); + if (configuration.isUseMetadataMeasurementName()) { + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, + itemName); + } if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index afdaa6d1c4a2b..fdb8aed8cebc3 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -94,8 +94,10 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { private String calculateMeasurementName(String itemName) { String name = itemName; - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadata(configuration, metadataRegistry, name, - itemName); + if (configuration.isUseMetadataMeasurementName()) { + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, + itemName); + } if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); From 4c04d7df1f9273fcdaa5b52006862ff189e74168 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Fri, 19 Feb 2021 13:45:13 +0100 Subject: [PATCH 08/16] Refactored without configuration Test failure Signed-off-by: Johannes Ott --- .../README.md | 86 ++++++++++++++----- .../internal/InfluxDBConfiguration.java | 7 -- .../internal/ItemToStorePointCreator.java | 6 +- ...Influx1FilterCriteriaQueryCreatorImpl.java | 7 +- ...Influx2FilterCriteriaQueryCreatorImpl.java | 10 +-- ...luxFilterCriteriaQueryCreatorImplTest.java | 69 ++++++--------- .../internal/ItemToStorePointCreatorTest.java | 11 ++- 7 files changed, 105 insertions(+), 91 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/README.md b/bundles/org.openhab.persistence.influxdb/README.md index 016fb0b743f4e..7080f3d0551a9 100644 --- a/bundles/org.openhab.persistence.influxdb/README.md +++ b/bundles/org.openhab.persistence.influxdb/README.md @@ -1,18 +1,16 @@ # InfluxDB (0.9 and newer) Persistence -This service allows you to persist and query states using the [InfluxDB](https://www.influxdata.com/products/influxdb-overview/) and [InfluxDB 2.0](https://v2.docs.influxdata.com/v2.0/) time series database. The persisted values can be queried from within openHAB. +This service allows you to persist and query states using the [InfluxDB](https://www.influxdata.com/products/influxdb-overview/) and [InfluxDB 2.0](https://v2.docs.influxdata.com/v2.0/) time series database. The persisted values can be queried from within openHAB. There also are nice tools on the web for visualizing InfluxDB time series, such as [Grafana](http://grafana.org/) and new Influx DB 2.0 version introduces [powerful data processing features.](https://docs.influxdata.com/influxdb/v2.0/process-data/get-started/) ## Database Structure - - This service allows you to persist and query states using the time series database. -- The states of an item are persisted in *measurements* points with names equal to the name of the item, or the alias, if one is provided. In both variants, a *tag* named "item" is added, containing the item name. - All values are stored in a *field* called "value" using the following types: - - **float** for DecimalType and QuantityType - - **integer** for `OnOffType` and `OpenClosedType` (values are stored using 0 or 1) and `DateTimeType` (milliseconds since 1970-01-01T00:00:00Z) - - **string** for the rest of types - +- The states of an item are persisted in _measurements_ points with names equal to the name of the item, or the alias, if one is provided. In both variants, a _tag_ named "item" is added, containing the item name. + All values are stored in a _field_ called "value" using the following types: + - **float** for DecimalType and QuantityType + - **integer** for `OnOffType` and `OpenClosedType` (values are stored using 0 or 1) and `DateTimeType` (milliseconds since 1970-01-01T00:00:00Z) + - **string** for the rest of types - If configured, extra tags for item category, label or type can be added fore each point. Some example entries for an item with the name "speedtest" without any further configuration would look like this: @@ -22,34 +20,78 @@ Some example entries for an item with the name "speedtest" without any further c |> range(start: -30d) |> filter(fn: (r) => r._measurement == "speedtest") name: speedtest - + _time _item _value ----- ----- ------ 1558302027124000000 speedtest 123289369.0 1558332852716000000 speedtest 80423789.0 - ## Prerequisites First of all you have to setup and run an InfluxDB 1.X or 2.X server. -This is very easy and you will find good documentation on it on the +This is very easy and you will find good documentation on it on the [InfluxDB web site for 2.X version](https://v2.docs.influxdata.com/v2.0/get-started/) and [InfluxDB web site for 1.X version](https://docs.influxdata.com/influxdb/v1.7/). ## Configuration This service can be configured in the file `services/influxdb.cfg`. -| Property | Default | Required | Description | -|------------------------------------|-------------------------|----------|------------------------------------------| -| version | V1 | No | InfluxDB database version V1 for 1.X and V2 for 2.x| -| url | http://127.0.0.1:8086 | No | database URL | -| user | openhab | No | name of the database user, e.g. `openhab`| -| password | | No(*) | password of the database user you choose | -| token | | No(*) | token to authenticate the database (only for V2) [Intructions about how to create one](https://v2.docs.influxdata.com/v2.0/security/tokens/create-token/) | -| db | openhab | No | name of the database for V1 and name of the organization for V2 | -| retentionPolicy | autogen | No | name of the retention policy for V1 and name of the bucket for V2 | +| Property | Default | Required | Description | +| --------------- | --------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| version | V1 | No | InfluxDB database version V1 for 1.X and V2 for 2.x | +| url | http://127.0.0.1:8086 | No | database URL | +| user | openhab | No | name of the database user, e.g. `openhab` | +| password | | No(\*) | password of the database user you choose | +| token | | No(\*) | token to authenticate the database (only for V2) [Intructions about how to create one](https://v2.docs.influxdata.com/v2.0/security/tokens/create-token/) | +| db | openhab | No | name of the database for V1 and name of the organization for V2 | +| retentionPolicy | autogen | No | name of the retention policy for V1 and name of the bucket for V2 | -(*) For 1.X version you must provide user and password, for 2.X you can use user and password or a token. That means -that if you use all default values at minimum you must provide a password or a token. +(\*) For 1.X version you must provide user and password, for 2.X you can use user and password or a token. That means +that if you use all default values at minimum you must provide a password or a token. All item- and event-related configuration is defined in the file `persistence/influxdb.persist`. + +### Additional configuration for better filtering options in InfluxDB + +By default persistence writes the data to a `measurement` name equals to the `item's name` and adds a tag with key item and value `item's name` as well. + +For more options to filter data in InfluxDB you can configure service and single items with more data. + +#### Item Metadata + +By setting the `influxdb` metadata key you can change the name of the measurement by setting the desired name as metadata value and at additional tags for structuring your data. For example you can add a floor tag to all sensors to filter all sensors from first floor or combine all temperature sensors into one measurement. + +The item configuration will look like this: + +``` +Group:Number:AVG gTempSensors + +Number:Temperature tempLivingRoom (gTempSensors) { influxdb="temperature" [floor="groundfloor"] } +Number:Temperature tempKitchen (gTempSensors) { influxdb="temperature" [floor="groundfloor"] } + + +Number:Temperature tempBedRoom (gTempSensors) { influxdb="temperature" [floor="firstfloor"] } +Number:Temperature tempBath (gTempSensors) { influxdb="temperature" [floor="firstfloor"] } + +``` + +This will end up with one measurement named temperature and four different series inside: + +``` +temperature,item=tempLivingRoom,floor=groundfloor +temperature,item=tempKitchen,floor=groundfloor +temperature,item=tempBedRoom,floor=firstfloor +temperature,item=tempBath,floor=firstfloor +``` + +You can now easily select all temperatures of firstfloor or average temperature of groundfloor. + +#### Extended automatic tagging + +Beside the metadata tags there are additional configuration parameters of the service to activate different automatic tags generation. + +| Property | Default | Required | Description | +| -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------- | +| addCategoryTag | false | no | Should the category of the item be included as tag "category"? If no category is set, "n/a" is used. | +| addTypeTag | false | no | Should the item type be included as tag "type"? | +| addLabelTag | false | no | Should the item label be included as tag "label"? If no label is set, "n/a" is used. | diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java index 5e00750ac1cd9..933d657e40efc 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBConfiguration.java @@ -36,7 +36,6 @@ public class InfluxDBConfiguration { public static final String RETENTION_POLICY_PARAM = "retentionPolicy"; public static final String VERSION_PARAM = "version"; public static final String REPLACE_UNDERSCORE_PARAM = "replaceUnderscore"; - public static final String META_MEASUREMENT_NAME = "useMetadataMeasurementName"; public static final String ADD_CATEGORY_TAG_PARAM = "addCategoryTag"; public static final String ADD_LABEL_TAG_PARAM = "addLabelTag"; public static final String ADD_TYPE_TAG_PARAM = "addTypeTag"; @@ -50,7 +49,6 @@ public class InfluxDBConfiguration { private final String retentionPolicy; private final InfluxDBVersion version; - private final boolean useMetadataMeasurementName; private final boolean replaceUnderscore; private final boolean addCategoryTag; private final boolean addTypeTag; @@ -65,7 +63,6 @@ public InfluxDBConfiguration(Map config) { retentionPolicy = (String) config.getOrDefault(RETENTION_POLICY_PARAM, "autogen"); version = parseInfluxVersion(config.getOrDefault(VERSION_PARAM, InfluxDBVersion.V1.name())); - useMetadataMeasurementName = getConfigBooleanValue(config, META_MEASUREMENT_NAME, false); replaceUnderscore = getConfigBooleanValue(config, REPLACE_UNDERSCORE_PARAM, false); addCategoryTag = getConfigBooleanValue(config, ADD_CATEGORY_TAG_PARAM, false); addLabelTag = getConfigBooleanValue(config, ADD_LABEL_TAG_PARAM, false); @@ -147,10 +144,6 @@ public boolean isReplaceUnderscore() { return replaceUnderscore; } - public boolean isUseMetadataMeasurementName() { - return useMetadataMeasurementName; - } - public boolean isAddCategoryTag() { return addCategoryTag; } diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java index 70f22127f2405..9f57af6dbad3c 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreator.java @@ -64,10 +64,8 @@ public ItemToStorePointCreator(InfluxDBConfiguration configuration, @Nullable Me private String calculateMeasurementName(Item item, @Nullable String storeAlias) { String name = storeAlias != null && !storeAlias.isBlank() ? storeAlias : item.getName(); - if (configuration.isUseMetadataMeasurementName()) { - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, - item.getName()); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, + item.getName()); if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index fe3f15cc4a5ee..2a52df9954603 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -61,7 +61,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { Where where = select.where(); - if (configuration.isUseMetadataMeasurementName() && hasCriteriaName) { + if (!(itemName == null || tableName.equals(itemName))) { where = where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName)); } @@ -105,10 +105,7 @@ private String calculateTableName(@Nullable String itemName) { String name = itemName; - if (configuration.isUseMetadataMeasurementName()) { - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, - itemName); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, itemName); if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java index fdb8aed8cebc3..5f1676d717ce3 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx2/Influx2FilterCriteriaQueryCreatorImpl.java @@ -65,8 +65,9 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { String itemName = criteria.getItemName(); if (itemName != null) { - flux = flux.filter(measurement().equal(calculateMeasurementName(itemName))); - if (configuration.isUseMetadataMeasurementName()) { + String measurementName = calculateMeasurementName(itemName); + flux = flux.filter(measurement().equal(measurementName)); + if (!measurementName.equals(itemName)) { flux = flux.filter(tag("item").equal(itemName)); } } @@ -94,10 +95,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { private String calculateMeasurementName(String itemName) { String name = itemName; - if (configuration.isUseMetadataMeasurementName()) { - name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, - itemName); - } + name = InfluxDBMetadataUtils.calculateMeasurementNameFromMetadataIfPresent(metadataRegistry, name, itemName); if (configuration.isReplaceUnderscore()) { name = name.replace('_', '.'); diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java index 50882978b3397..0cbd5d8a0f8f0 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java @@ -59,8 +59,6 @@ public class InfluxFilterCriteriaQueryCreatorImplTest { @BeforeEach public void before() { - when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); - instanceV1 = new Influx1FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); instanceV2 = new Influx2FilterCriteriaQueryCreatorImpl(influxDBConfiguration, metadataRegistry); } @@ -85,45 +83,6 @@ public void testSimpleItemQueryWithoutParams() { + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); } - @Test - public void testMeasurementNameFromMetadata() { - FilterCriteria criteria = createBaseCriteria(); - MetadataKey metadataKey = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, "sampleItem"); - - when(metadataRegistry.get(metadataKey)) - .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); - - String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem;")); - - String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" - + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); - - when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(true); - - queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.measurementName WHERE item = 'sampleItem';")); - - queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV2, - equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" - + "|> filter(fn: (r) => r[\"_measurement\"] == \"measurementName\")\n\t" - + "|> filter(fn: (r) => r[\"item\"] == \"sampleItem\")")); - - when(metadataRegistry.get(metadataKey)) - .thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2"))); - - queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem WHERE item = 'sampleItem';")); - - queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV2, - equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" - + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")\n\t" - + "|> filter(fn: (r) => r[\"item\"] == \"sampleItem\")")); - } - @Test public void testEscapeSimpleItem() { FilterCriteria criteria = createBaseCriteria("sample.Item"); @@ -225,4 +184,32 @@ private FilterCriteria createBaseCriteria(String sampleItem) { criteria.setOrdering(null); return criteria; } + + @Test + public void testMeasurementNameFromMetadata() { + FilterCriteria criteria = createBaseCriteria(); + MetadataKey metadataKey = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, "sampleItem"); + + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); + + String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV1, equalTo("SELECT value FROM origin.measurementName WHERE item = 'sampleItem';")); + + String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV2, + equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + + "|> filter(fn: (r) => r[\"_measurement\"] == \"measurementName\")\n\t" + + "|> filter(fn: (r) => r[\"item\"] == \"sampleItem\")")); + + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2"))); + + queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem;")); + + queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); + assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" + + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); + } } diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java index 042d44065b6a1..38bbe9846a769 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java @@ -54,7 +54,6 @@ public void before() { when(influxDBConfiguration.isAddLabelTag()).thenReturn(false); when(influxDBConfiguration.isAddTypeTag()).thenReturn(false); when(influxDBConfiguration.isReplaceUnderscore()).thenReturn(false); - when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); instance = new ItemToStorePointCreator(influxDBConfiguration, metadataRegistry); } @@ -150,22 +149,22 @@ public void shouldUseMeasurementNameFromMetadataIfConfigured() { InfluxPoint point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); - when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(true); - point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); - assertThat(point.getTags(), hasEntry("item", "myitem")); + assertThat(point.getTags(), hasEntry("item", item.getName())); when(metadataRegistry.get(metadataKey)) .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo("measurementName")); - assertThat(point.getTags(), hasEntry("item", "myitem")); + assertThat(point.getTags(), hasEntry("item", item.getName())); - when(influxDBConfiguration.isUseMetadataMeasurementName()).thenReturn(false); + when(metadataRegistry.get(metadataKey)) + .thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2"))); point = instance.convert(item, null); assertThat(point.getMeasurementName(), equalTo(item.getName())); + assertThat(point.getTags(), hasEntry("item", item.getName())); } } From 63aebb9027cb9576f0e6b290cc2ea982ac5d3328 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Fri, 19 Feb 2021 15:49:47 +0100 Subject: [PATCH 09/16] Added failing Test for sample.Item Signed-off-by: Johannes Ott --- .../influxdb/internal/ItemToStorePointCreatorTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java index 38bbe9846a769..281305b444b81 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java @@ -80,6 +80,14 @@ private static Stream convertBasicItem() { return Stream.of(5, 5.5, 5L); } + @Test + public void testEscapeSimpleItem() { + NumberItem item = ItemTestHelper.createNumberItem("sample.Item", 5); + InfluxPoint point = instance.convert(item, null); + + assertThat(point.getMeasurementName(), equalTo(item.getName())); + } + @Test public void shouldUseAliasAsMeasurementNameIfProvided() { NumberItem item = ItemTestHelper.createNumberItem("myitem", 5); From 70f4a93762fb2f05512cc2917bdc31b601daf3bc Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Fri, 19 Feb 2021 19:32:11 +0100 Subject: [PATCH 10/16] Removed wrong testcase and review comment in README Signed-off-by: Johannes Ott --- bundles/org.openhab.persistence.influxdb/README.md | 2 +- .../InfluxFilterCriteriaQueryCreatorImplTest.java | 12 ------------ .../internal/ItemToStorePointCreatorTest.java | 10 +--------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/README.md b/bundles/org.openhab.persistence.influxdb/README.md index 7080f3d0551a9..6c7cd5c6e58a8 100644 --- a/bundles/org.openhab.persistence.influxdb/README.md +++ b/bundles/org.openhab.persistence.influxdb/README.md @@ -6,7 +6,7 @@ There also are nice tools on the web for visualizing InfluxDB time series, such ## Database Structure - This service allows you to persist and query states using the time series database. -- The states of an item are persisted in _measurements_ points with names equal to the name of the item, or the alias, if one is provided. In both variants, a _tag_ named "item" is added, containing the item name. +- The states of an item are persisted in _measurements_ points with names equal to the name of the item, its alias, or from some metadata depending on the configuration. In all variants, a tag named "item" is added, containing the item name. All values are stored in a _field_ called "value" using the following types: - **float** for DecimalType and QuantityType - **integer** for `OnOffType` and `OpenClosedType` (values are stored using 0 or 1) and `DateTimeType` (milliseconds since 1970-01-01T00:00:00Z) diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java index 0cbd5d8a0f8f0..5bd7bf033141b 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java @@ -83,18 +83,6 @@ public void testSimpleItemQueryWithoutParams() { + "|> filter(fn: (r) => r[\"_measurement\"] == \"sampleItem\")")); } - @Test - public void testEscapeSimpleItem() { - FilterCriteria criteria = createBaseCriteria("sample.Item"); - - String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.\"sample.Item\";")); - - String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" - + "|> filter(fn: (r) => r[\"_measurement\"] == \"sample.Item\")")); - } - @Test public void testSimpleUnboundedItemWithoutParams() { FilterCriteria criteria = new FilterCriteria(); diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java index 281305b444b81..5b593bb2c7fb8 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java @@ -80,14 +80,6 @@ private static Stream convertBasicItem() { return Stream.of(5, 5.5, 5L); } - @Test - public void testEscapeSimpleItem() { - NumberItem item = ItemTestHelper.createNumberItem("sample.Item", 5); - InfluxPoint point = instance.convert(item, null); - - assertThat(point.getMeasurementName(), equalTo(item.getName())); - } - @Test public void shouldUseAliasAsMeasurementNameIfProvided() { NumberItem item = ItemTestHelper.createNumberItem("myitem", 5); @@ -150,7 +142,7 @@ public void shouldStoreMetadataAsTagsIfProvided() { } @Test - public void shouldUseMeasurementNameFromMetadataIfConfigured() { + public void shouldUseMeasurementNameFromMetadataIfProvided() { NumberItem item = ItemTestHelper.createNumberItem("myitem", 5); MetadataKey metadataKey = new MetadataKey(InfluxDBPersistenceService.SERVICE_NAME, item.getName()); From 15038f34dccb825f8fd27c2fb4740dd0e1e1e89a Mon Sep 17 00:00:00 2001 From: Joan Pujol Date: Fri, 26 Feb 2021 23:05:01 +0100 Subject: [PATCH 11/16] Minor documentation changes Signed-off-by: Joan Pujol Signed-off-by: Johannes Ott --- .../README.md | 27 ++++++++++++------- .../main/resources/OH-INF/config/config.xml | 4 +-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/README.md b/bundles/org.openhab.persistence.influxdb/README.md index 6c7cd5c6e58a8..f087c9a71d2a7 100644 --- a/bundles/org.openhab.persistence.influxdb/README.md +++ b/bundles/org.openhab.persistence.influxdb/README.md @@ -28,7 +28,7 @@ Some example entries for an item with the name "speedtest" without any further c ## Prerequisites -First of all you have to setup and run an InfluxDB 1.X or 2.X server. +First of all, you have to setup and run an InfluxDB 1.X or 2.X server. This is very easy and you will find good documentation on it on the [InfluxDB web site for 2.X version](https://v2.docs.influxdata.com/v2.0/get-started/) and [InfluxDB web site for 1.X version](https://docs.influxdata.com/influxdb/v1.7/). @@ -51,15 +51,15 @@ that if you use all default values at minimum you must provide a password or a t All item- and event-related configuration is defined in the file `persistence/influxdb.persist`. -### Additional configuration for better filtering options in InfluxDB +### Additional configuration for customized storage options in InfluxDB -By default persistence writes the data to a `measurement` name equals to the `item's name` and adds a tag with key item and value `item's name` as well. +By default, the plugin writes the data to a `measurement` name equals to the `item's name` and adds a tag with key item and value `item's name` as well. +You can customize that behavior and use a single measurement for several items using item metadata. -For more options to filter data in InfluxDB you can configure service and single items with more data. +#### Measurement name by Item Metadata -#### Item Metadata - -By setting the `influxdb` metadata key you can change the name of the measurement by setting the desired name as metadata value and at additional tags for structuring your data. For example you can add a floor tag to all sensors to filter all sensors from first floor or combine all temperature sensors into one measurement. +By setting the `influxdb` metadata key you can change the name of the measurement by setting the desired name as metadata value. +You can also add additional tags for structuring your data. For example, you can add a floor tag to all sensors to filter all sensors from the first floor or combine all temperature sensors into one measurement. The item configuration will look like this: @@ -75,8 +75,15 @@ Number:Temperature tempBath (gTempSensors) { influxdb="temperature" [floor="firs ``` -This will end up with one measurement named temperature and four different series inside: +You can also set the `inflxdb` metadata using the UI. From each item configuration screen do: + +`Metadata` → `Add Metadata` → `Enter Custom Namespace` → Enter `influxdb` as namespace name → And enter your desired item name in value field. i.e.: + value: temperature + config: {} + + +This will end up with one measurement named temperature and four different series inside: ``` temperature,item=tempLivingRoom,floor=groundfloor temperature,item=tempKitchen,floor=groundfloor @@ -84,11 +91,11 @@ temperature,item=tempBedRoom,floor=firstfloor temperature,item=tempBath,floor=firstfloor ``` -You can now easily select all temperatures of firstfloor or average temperature of groundfloor. +You can now easily select all temperatures of the firstfloor or the average temperature of the groundfloor. #### Extended automatic tagging -Beside the metadata tags there are additional configuration parameters of the service to activate different automatic tags generation. +Besides the metadata tags, there are additional configuration parameters to activate different automatic tags generation. | Property | Default | Required | Description | | -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------- | diff --git a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml index 8b7f4d4b95e10..1f3e9e8229e44 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml @@ -14,7 +14,7 @@ - This group defines additional tags which can be added. + This group defines additional tags which can be added to your measurements. false @@ -84,7 +84,7 @@ If true uses metadata from item influxdb metadata value as name for measurement instead of item name. If - metadata value is not set item name is used again. + metadata value is not set item name is used. false From c2e01303e264f16bb24e1bcbb6628a4c992cacb4 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sat, 27 Feb 2021 22:22:52 +0100 Subject: [PATCH 12/16] Update bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml Co-authored-by: Joan Pujol Signed-off-by: Johannes Ott --- .../src/main/resources/OH-INF/config/config.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml index 1f3e9e8229e44..dc968cae1a8c2 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml @@ -81,14 +81,6 @@ false - - - If true uses metadata from item influxdb metadata value as name for measurement instead of item name. If - metadata value is not set item name is used. - - false - - Should the category of the item be included as tag "category"? If no category is set, "n/a" is From 46c890613699c2e809229383843a03782dbacbf7 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sat, 27 Feb 2021 22:23:12 +0100 Subject: [PATCH 13/16] Update bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java Co-authored-by: Joan Pujol Signed-off-by: Johannes Ott --- .../internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 2a52df9954603..1a8530543d36e 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -61,7 +61,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { Where where = select.where(); - if (!(itemName == null || tableName.equals(itemName))) { + if (itemName != null && !tableName.equals(itemName))) { where = where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName)); } From a1ee720c06325e79960d554bf210d08f441eb530 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sat, 27 Feb 2021 23:10:33 +0100 Subject: [PATCH 14/16] Syntax error in review suggestion Signed-off-by: Johannes Ott --- .../internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index 1a8530543d36e..d82205fc874d9 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -61,7 +61,7 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { Where where = select.where(); - if (itemName != null && !tableName.equals(itemName))) { + if (itemName != null && !tableName.equals(itemName)) { where = where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName)); } From c9fa173b06447bcb2aa985948bd37e23eac26860 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sat, 27 Feb 2021 23:11:01 +0100 Subject: [PATCH 15/16] Small typo fixed Signed-off-by: Johannes Ott --- bundles/org.openhab.persistence.influxdb/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/README.md b/bundles/org.openhab.persistence.influxdb/README.md index f087c9a71d2a7..cfc8e2e62f9df 100644 --- a/bundles/org.openhab.persistence.influxdb/README.md +++ b/bundles/org.openhab.persistence.influxdb/README.md @@ -75,15 +75,15 @@ Number:Temperature tempBath (gTempSensors) { influxdb="temperature" [floor="firs ``` -You can also set the `inflxdb` metadata using the UI. From each item configuration screen do: +You can also set the `influxdb` metadata using the UI. From each item configuration screen do: -`Metadata` → `Add Metadata` → `Enter Custom Namespace` → Enter `influxdb` as namespace name → And enter your desired item name in value field. i.e.: +`Metadata` → `Add Metadata` → `Enter Custom Namespace` → Enter `influxdb` as namespace name → And enter your desired item name in value field. i.e.: value: temperature config: {} - This will end up with one measurement named temperature and four different series inside: + ``` temperature,item=tempLivingRoom,floor=groundfloor temperature,item=tempKitchen,floor=groundfloor From 16a2d255b94301f59515627ea93b77a9d8742b38 Mon Sep 17 00:00:00 2001 From: Johannes Ott Date: Sun, 28 Feb 2021 01:06:00 +0100 Subject: [PATCH 16/16] Fixed bug in V1 query Signed-off-by: Johannes Ott --- ...Influx1FilterCriteriaQueryCreatorImpl.java | 5 +++-- .../influx1/InfluxDB1RepositoryImpl.java | 13 +++++++++++-- ...luxFilterCriteriaQueryCreatorImplTest.java | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java index d82205fc874d9..6ee99b551fb7c 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/Influx1FilterCriteriaQueryCreatorImpl.java @@ -56,8 +56,9 @@ public String createQuery(FilterCriteria criteria, String retentionPolicy) { tableName = calculateTableName(itemName); - Select select = select(COLUMN_VALUE_NAME_V1).fromRaw(null, - fullQualifiedTableName(retentionPolicy, tableName, hasCriteriaName)); + Select select = select().column("\"" + COLUMN_VALUE_NAME_V1 + "\"::field") + .column("\"" + TAG_ITEM_NAME + "\"::tag") + .fromRaw(null, fullQualifiedTableName(retentionPolicy, tableName, hasCriteriaName)); Where where = select.where(); diff --git a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/InfluxDB1RepositoryImpl.java b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/InfluxDB1RepositoryImpl.java index 7f406168dfb1c..094c8ab25c448 100644 --- a/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/InfluxDB1RepositoryImpl.java +++ b/bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/influx1/InfluxDB1RepositoryImpl.java @@ -15,6 +15,7 @@ import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.COLUMN_TIME_NAME_V1; import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.COLUMN_VALUE_NAME_V1; import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.FIELD_VALUE_NAME; +import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_ITEM_NAME; import java.time.Instant; import java.util.ArrayList; @@ -42,8 +43,10 @@ /** * Implementation of {@link InfluxDBRepository} for InfluxDB 1.0 * - * @author Joan Pujol Espinar - Initial contribution. Most code has been moved from - * {@link org.openhab.persistence.influxdb.InfluxDBPersistenceService} where it was in previous version + * @author Joan Pujol Espinar - Initial contribution. Most code has been moved + * from + * {@link org.openhab.persistence.influxdb.InfluxDBPersistenceService} + * where it was in previous version */ @NonNullByDefault public class InfluxDB1RepositoryImpl implements InfluxDBRepository { @@ -178,12 +181,15 @@ private List convertClientResutToRepository(List if (columns != null) { Integer timestampColumn = null; Integer valueColumn = null; + Integer itemNameColumn = null; for (int i = 0; i < columns.size(); i++) { String columnName = columns.get(i); if (columnName.equals(COLUMN_TIME_NAME_V1)) { timestampColumn = i; } else if (columnName.equals(COLUMN_VALUE_NAME_V1)) { valueColumn = i; + } else if (columnName.equals(TAG_ITEM_NAME)) { + itemNameColumn = i; } } if (valueColumn == null || timestampColumn == null) { @@ -193,6 +199,9 @@ private List convertClientResutToRepository(List Double rawTime = (Double) valuess.get(i).get(timestampColumn); Instant time = Instant.ofEpochMilli(rawTime.longValue()); Object value = valuess.get(i).get(valueColumn); + if (itemNameColumn != null) { + itemName = (String) valuess.get(i).get(itemNameColumn); + } logger.trace("adding historic item {}: time {} value {}", itemName, time, value); rows.add(new InfluxRow(time, itemName, value)); } diff --git a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java index 5bd7bf033141b..3b0ed51a0ab72 100644 --- a/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java +++ b/bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxFilterCriteriaQueryCreatorImplTest.java @@ -76,7 +76,7 @@ public void testSimpleItemQueryWithoutParams() { FilterCriteria criteria = createBaseCriteria(); String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem;")); + assertThat(queryV1, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem;")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" @@ -89,7 +89,7 @@ public void testSimpleUnboundedItemWithoutParams() { criteria.setOrdering(null); String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin./.*/;")); + assertThat(queryV1, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin./.*/;")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)")); @@ -105,8 +105,8 @@ public void testRangeCriteria() { String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); String expectedQueryV1 = String.format( - "SELECT value FROM origin.sampleItem WHERE time >= '%s' AND time <= '%s';", now.toInstant(), - tomorrow.toInstant()); + "SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem WHERE time >= '%s' AND time <= '%s';", + now.toInstant(), tomorrow.toInstant()); assertThat(queryV1, equalTo(expectedQueryV1)); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); @@ -124,7 +124,7 @@ public void testValueOperator() { criteria.setState(new PercentType(90)); String query = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(query, equalTo("SELECT value FROM origin.sampleItem WHERE value <= 90;")); + assertThat(query, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem WHERE value <= 90;")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, @@ -140,7 +140,7 @@ public void testPagination() { criteria.setPageSize(10); String query = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(query, equalTo("SELECT value FROM origin.sampleItem LIMIT 10 OFFSET 20;")); + assertThat(query, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem LIMIT 10 OFFSET 20;")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t" @@ -153,7 +153,7 @@ public void testOrdering() { criteria.setOrdering(FilterCriteria.Ordering.ASCENDING); String query = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(query, equalTo("SELECT value FROM origin.sampleItem ORDER BY time ASC;")); + assertThat(query, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem ORDER BY time ASC;")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, @@ -182,7 +182,8 @@ public void testMeasurementNameFromMetadata() { .thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2"))); String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.measurementName WHERE item = 'sampleItem';")); + assertThat(queryV1, equalTo( + "SELECT \"value\"::field,\"item\"::tag FROM origin.measurementName WHERE item = 'sampleItem';")); String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, @@ -194,7 +195,7 @@ public void testMeasurementNameFromMetadata() { .thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2"))); queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY); - assertThat(queryV1, equalTo("SELECT value FROM origin.sampleItem;")); + assertThat(queryV1, equalTo("SELECT \"value\"::field,\"item\"::tag FROM origin.sampleItem;")); queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY); assertThat(queryV2, equalTo("from(bucket:\"origin\")\n\t" + "|> range(start:-100y)\n\t"