]> git.basschouten.com Git - openhab-addons.git/commitdiff
[influxdb] Fixes issue 8798 and 8697 problems storing integer types (#8831)
authorJoan Pujol <joanpujol@gmail.com>
Thu, 22 Oct 2020 08:26:21 +0000 (10:26 +0200)
committerGitHub <noreply@github.com>
Thu, 22 Oct 2020 08:26:21 +0000 (10:26 +0200)
* Update documentation with changed Influx2 RC port
* Fix problem with non decimal numeric types

Improve documentation with more explicit information about Influx types used
Implement toString to InfluxPoint to allow some trace info to be useful in case it's needed

Fixes #8697
Fixes #8798

Signed-off-by: Joan Pujol <joanpujol@gmail.com>
bundles/org.openhab.persistence.influxdb/README.md
bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxDBStateConvertUtils.java
bundles/org.openhab.persistence.influxdb/src/main/java/org/openhab/persistence/influxdb/internal/InfluxPoint.java
bundles/org.openhab.persistence.influxdb/src/main/resources/OH-INF/config/config.xml
bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ConfigurationTestHelper.java
bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/InfluxDBStateConvertUtilsTest.java
bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemTestHelper.java
bundles/org.openhab.persistence.influxdb/src/test/java/org/openhab/persistence/influxdb/internal/ItemToStorePointCreatorTest.java

index beb39efc286826af98a27a999dd1cfbe33b5bb36..3abf90181387feb5e8adfabd5a01ef98468d984b 100644 (file)
@@ -1,14 +1,19 @@
 # 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. There also are nice tools on the web for visualizing InfluxDB time series, such as [Grafana](http://grafana.org/).
+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 integers or doubles if possible,`OnOffType` and `OpenClosedType` values are stored using 0 or 1.
-- If configured extra tags for item category, label or type can be added fore each point.
+ 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:
 
index 8670b8a1f7409b7de28781fa040f41d191cbc1b0..62f096fad398d790f16e59bacdf53a2710b542ce 100644 (file)
@@ -69,9 +69,9 @@ public class InfluxDBStateConvertUtils {
         } else if (state instanceof PointType) {
             value = point2String((PointType) state);
         } else if (state instanceof DecimalType) {
-            value = convertBigDecimalToNum(((DecimalType) state).toBigDecimal());
+            value = ((DecimalType) state).toBigDecimal();
         } else if (state instanceof QuantityType<?>) {
-            value = convertBigDecimalToNum(((QuantityType<?>) state).toBigDecimal());
+            value = ((QuantityType<?>) state).toBigDecimal();
         } else if (state instanceof OnOffType) {
             value = state == OnOffType.ON ? DIGITAL_VALUE_ON : DIGITAL_VALUE_OFF;
         } else if (state instanceof OpenClosedType) {
@@ -166,21 +166,4 @@ public class InfluxDBStateConvertUtils {
         }
         return buf.toString(); // latitude, longitude, altitude
     }
-
-    /**
-     * This method returns an integer if possible if not a double is returned. This is an optimization
-     * for influxdb because integers have less overhead.
-     *
-     * @param value the BigDecimal to be converted
-     * @return A double if possible else a double is returned.
-     */
-    private static Object convertBigDecimalToNum(BigDecimal value) {
-        Object convertedValue;
-        if (value.scale() == 0) {
-            convertedValue = value.toBigInteger();
-        } else {
-            convertedValue = value.doubleValue();
-        }
-        return convertedValue;
-    }
 }
index bfad354d3c557dbc05bd8d934736990c69ff7761..531a13a1f5f908b1cb6718c8fb8c9a23dc3e3758 100644 (file)
@@ -88,4 +88,10 @@ public class InfluxPoint {
             return new InfluxPoint(this);
         }
     }
+
+    @Override
+    public String toString() {
+        return "InfluxPoint{" + "measurementName='" + measurementName + '\'' + ", time=" + time + ", value=" + value
+                + ", tags=" + tags + '}';
+    }
 }
index b8fe1a0e285e22e49c5b348d8b70e945a9aaa146..3ee4fd5dd8038078d37179f0404315da3b7fc763 100644 (file)
@@ -27,7 +27,7 @@
                <parameter name="url" type="text" required="true" groupName="connection">
                        <context>url</context>
                        <label>Database URL</label>
-                       <description>The database URL, e.g. http://127.0.0.1:8086 or http://127.0.0.1:9999</description>
+                       <description>The database URL, e.g. http://127.0.0.1:8086</description>
                        <default>http://127.0.0.1:8086</default>
                </parameter>
 
index c9b28768324aa4afd42e1b34094cfb856ea83587..639a4e51101707fc7a3b87fea23fc44c6c866566 100644 (file)
@@ -32,7 +32,7 @@ public class ConfigurationTestHelper {
 
     public static Map<String, @Nullable Object> createValidConfigurationParameters() {
         Map<String, @Nullable Object> config = new HashMap<>();
-        config.put(URL_PARAM, "http://localhost:9999");
+        config.put(URL_PARAM, "http://localhost:8086");
         config.put(VERSION_PARAM, InfluxDBVersion.V2.name());
         config.put(TOKEN_PARAM, "sampletoken");
         config.put(DATABASE_PARAM, "openhab");
index a7ac2058d423ffe28b50e515be9d42a55b9d80f9..d44032ddca6dd775dc7c0ec8736c38881409be8d 100644 (file)
@@ -13,7 +13,8 @@
 package org.openhab.persistence.influxdb.internal;
 
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
 
 import java.math.BigDecimal;
 import java.time.Instant;
@@ -22,6 +23,8 @@ import java.time.ZonedDateTime;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.openhab.core.library.items.ContactItem;
 import org.openhab.core.library.items.DateTimeItem;
 import org.openhab.core.library.items.NumberItem;
@@ -40,7 +43,13 @@ public class InfluxDBStateConvertUtilsTest {
     @Test
     public void convertDecimalState() {
         DecimalType decimalType = new DecimalType(new BigDecimal("1.12"));
-        assertThat((Double) InfluxDBStateConvertUtils.stateToObject(decimalType), closeTo(1.12, 0.01));
+        assertThat(InfluxDBStateConvertUtils.stateToObject(decimalType), is(new BigDecimal("1.12")));
+    }
+
+    @Test
+    public void convertIntegerDecimalState() {
+        DecimalType decimalType = new DecimalType(12L);
+        assertThat(InfluxDBStateConvertUtils.stateToObject(decimalType), is(new BigDecimal("12")));
     }
 
     @Test
@@ -57,9 +66,10 @@ public class InfluxDBStateConvertUtilsTest {
         assertThat(InfluxDBStateConvertUtils.stateToObject(type), equalTo(nowInMillis));
     }
 
-    @Test
-    public void convertDecimalToState() {
-        BigDecimal val = new BigDecimal("1.12");
+    @ParameterizedTest
+    @ValueSource(strings = { "1.12", "25" })
+    public void convertDecimalToState(String number) {
+        BigDecimal val = new BigDecimal(number);
         NumberItem item = new NumberItem("name");
         assertThat(InfluxDBStateConvertUtils.objectToState(val, item), equalTo(new DecimalType(val)));
     }
index ca2636a75c982f4e50a36fc869c0cef7bf5c8edc..66d4e3df7bf0becf1f1e40fb7603452892b4f35e 100644 (file)
@@ -22,9 +22,12 @@ import org.openhab.core.library.types.DecimalType;
 @NonNullByDefault
 public class ItemTestHelper {
 
-    public static NumberItem createNumberItem(String name, int value) {
+    public static NumberItem createNumberItem(String name, Number value) {
         NumberItem numberItem = new NumberItem(name);
-        numberItem.setState(new DecimalType(value));
+        if (value instanceof Integer || value instanceof Long)
+            numberItem.setState(new DecimalType(value.longValue()));
+        else
+            numberItem.setState(new DecimalType(value.doubleValue()));
         return numberItem;
     }
 }
index 7198a58aafdfa454def2c377403d986bd84e34cd..747322e0d11feaf40ef03c7d18b3d3900b6b40aa 100644 (file)
@@ -16,8 +16,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
 import static org.mockito.Mockito.when;
 
-import java.math.BigInteger;
+import java.math.BigDecimal;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import org.eclipse.jdt.annotation.DefaultLocation;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -25,6 +26,8 @@ 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.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.openhab.core.items.Metadata;
@@ -62,14 +65,19 @@ public class ItemToStorePointCreatorTest {
         metadataRegistry = null;
     }
 
-    @Test
-    public void convertBasicItem() {
-        NumberItem item = ItemTestHelper.createNumberItem("myitem", 5);
+    @ParameterizedTest
+    @MethodSource
+    public void convertBasicItem(Number number) {
+        NumberItem item = ItemTestHelper.createNumberItem("myitem", number);
         InfluxPoint point = instance.convert(item, null);
 
         assertThat(point.getMeasurementName(), equalTo(item.getName()));
         assertThat("Must Store item name", point.getTags(), hasEntry("item", item.getName()));
-        assertThat(point.getValue(), equalTo(new BigInteger("5")));
+        assertThat(point.getValue(), equalTo(new BigDecimal(number.toString())));
+    }
+
+    private static Stream<Number> convertBasicItem() {
+        return Stream.of(5, 5.5, 5L);
     }
 
     @Test