]> git.basschouten.com Git - openhab-addons.git/commitdiff
[luftdateninfo] Add internal sensor support (#10643)
authorBernd Weymann <bernd.weymann@gmail.com>
Thu, 13 May 2021 14:26:17 +0000 (16:26 +0200)
committerGitHub <noreply@github.com>
Thu, 13 May 2021 14:26:17 +0000 (16:26 +0200)
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
17 files changed:
bundles/org.openhab.binding.luftdateninfo/README.md
bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png [new file with mode: 0644]
bundles/org.openhab.binding.luftdateninfo/doc/logo-rund.png [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoConfiguration.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoHandlerFactory.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/BaseSensorHandler.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/ConditionHandler.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/HTTPHandler.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/NoiseHandler.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/PMHandler.java
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/Constants.java [new file with mode: 0644]
bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/ConditionHandlerTest.java
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/DTOTest.java
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerValueTest.java
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/PMHandlerTest.java
bundles/org.openhab.binding.luftdateninfo/src/test/resources/internal-data.json [new file with mode: 0644]

index 4b100712a32c40e6f8590b88a9be1b21f3429993..ff076ced1d5d4cf4d5271d4f4d2f4a5e7426c82b 100644 (file)
@@ -1,7 +1,5 @@
 # LuftdatenInfo Binding
 
-<img align="right" src="./doc/logo-rund.png"/>
-
 Binding for the Sensor Community [luftdaten.info](https://luftdaten.info/). The community provides instructions to build sensors on your own and they can be integrated into the database.
 With this binding you can integrate your sensor, a sensor nearby or even any sensors you want into openHAB.
 
@@ -21,10 +19,21 @@ There's no auto discovery. See Thing configuration how to setup a Sensor.
 
 ## Thing Configuration
 
+Choose either a local IP address of your personal owned sensor _or_ a sensor id of an external one.
+
 | Parameter       | Description                                                          |
 |-----------------|----------------------------------------------------------------------|
+| ipAddress       | Local IP address of your personal owned sensor                       |
 | sensorid        | Sensor ID obtained from https://deutschland.maps.sensor.community/   |
 
+### Local Sensor
+
+Please check in your browser if you can access your sensor with your local IP address.
+
+![Luftdaten.info Logo](doc/local-sensor.png)
+
+### External Sensor
+
 Perform the following steps to get the appropriate Sensor ID
 
 * Go to to [luftdaten.info map](https://deutschland.maps.sensor.community/)
@@ -69,9 +78,9 @@ Perform the following steps to get the appropriate Sensor ID
 luftdaten.things
 
 ```
-Thing luftdateninfo:particulate:pm_sensor   "PM Sensor"         [ sensorid=28842]
-Thing luftdateninfo:conditions:cond_sensor  "Condition Sensor"  [ sensorid=28843]
-Thing luftdateninfo:noise:noise_sensor      "Noise Sensor"      [ sensorid=39745]
+Thing luftdateninfo:particulate:pm_sensor   "PM Sensor"         [ ipAddress=192.168.178.50 ]
+Thing luftdateninfo:conditions:cond_sensor  "Condition Sensor"  [ sensorid=28843 ]
+Thing luftdateninfo:noise:noise_sensor      "Noise Sensor"      [ sensorid=39745 ]
 ```
 
 ### Items
diff --git a/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png b/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png
new file mode 100644 (file)
index 0000000..ccf4e6f
Binary files /dev/null and b/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png differ
diff --git a/bundles/org.openhab.binding.luftdateninfo/doc/logo-rund.png b/bundles/org.openhab.binding.luftdateninfo/doc/logo-rund.png
deleted file mode 100644 (file)
index 962c7a9..0000000
Binary files a/bundles/org.openhab.binding.luftdateninfo/doc/logo-rund.png and /dev/null differ
index 5fb55a0163ce8c8161a8049bc572b5bd818a7ca7..18a6597a1a9f2d2b01e7b3c37f605c9d223eb075 100644 (file)
@@ -13,6 +13,7 @@
 package org.openhab.binding.luftdateninfo.internal;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.luftdateninfo.internal.utils.Constants;
 
 /**
  * The {@link LuftdatenInfoConfiguration} class contains fields mapping thing configuration parameters.
@@ -22,5 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 @NonNullByDefault
 public class LuftdatenInfoConfiguration {
 
-    public int sensorid = -1;
+    public int sensorid = Constants.UNDEF;
+
+    public String ipAddress = Constants.EMPTY;
 }
index 5f7641eb3b19d8fb99519e39303e81e628f801fb..51b653a1f6eac31227dd2612291ed17de1952dda 100644 (file)
@@ -48,13 +48,9 @@ public class LuftdatenInfoHandlerFactory extends BaseThingHandlerFactory {
 
     @Override
     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
-        if (thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_PARTICULATE)
+        return (thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_PARTICULATE)
                 || thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_CONDITIONS)
-                || thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_NOISE)) {
-            return true;
-        } else {
-            return false;
-        }
+                || thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_NOISE));
     }
 
     @Override
index 97e7890f53bb4806d4bfcdaf31e8f712ab2903f3..57eb3d0c44348292a4830eeeaa64c026d2d81036 100644 (file)
 package org.openhab.binding.luftdateninfo.internal.handler;
 
 import java.time.LocalDateTime;
+import java.util.Optional;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.luftdateninfo.internal.LuftdatenInfoConfiguration;
+import org.openhab.binding.luftdateninfo.internal.utils.Constants;
 import org.openhab.binding.luftdateninfo.internal.utils.DateTimeUtils;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
@@ -48,9 +50,12 @@ public abstract class BaseSensorHandler extends BaseThingHandler {
     protected ThingStatus myThingStatus = ThingStatus.UNKNOWN;
     protected UpdateStatus lastUpdateStatus = UpdateStatus.UNKNOWN;
     protected @Nullable ScheduledFuture<?> refreshJob;
+    private Optional<String> sensorUrl = Optional.empty();
+    private boolean firstUpdate = true;
 
     public enum ConfigStatus {
-        OK,
+        INTERNAL_SENSOR_OK,
+        EXTERNAL_SENSOR_OK,
         IS_NULL,
         SENSOR_IS_NULL,
         SENSOR_ID_NEGATIVE,
@@ -88,6 +93,7 @@ public abstract class BaseSensorHandler extends BaseThingHandler {
 
     @Override
     public void initialize() {
+        firstUpdate = true;
         lifecycleStatus = LifecycleStatus.INITIALIZING;
         scheduler.execute(this::startUp);
     }
@@ -95,7 +101,7 @@ public abstract class BaseSensorHandler extends BaseThingHandler {
     private void startUp() {
         config = getConfigAs(LuftdatenInfoConfiguration.class);
         configStatus = checkConfig(config);
-        if (configStatus == ConfigStatus.OK) {
+        if (configStatus == ConfigStatus.INTERNAL_SENSOR_OK || configStatus == ConfigStatus.EXTERNAL_SENSOR_OK) {
             // start getting values
             dataUpdate();
         } else {
@@ -135,10 +141,16 @@ public abstract class BaseSensorHandler extends BaseThingHandler {
      */
     private ConfigStatus checkConfig(@Nullable LuftdatenInfoConfiguration c) {
         if (c != null) {
-            if (c.sensorid >= 0) {
-                return ConfigStatus.OK;
+            if (c.ipAddress != null && !Constants.EMPTY.equals(c.ipAddress)) {
+                sensorUrl = Optional.of("http://" + c.ipAddress + "/data.json");
+                return ConfigStatus.INTERNAL_SENSOR_OK;
             } else {
-                return ConfigStatus.SENSOR_ID_NEGATIVE;
+                if (c.sensorid >= 0) {
+                    sensorUrl = Optional.of("http://data.sensor.community/airrohr/v1/sensor/" + c.sensorid + "/");
+                    return ConfigStatus.EXTERNAL_SENSOR_OK;
+                } else {
+                    return ConfigStatus.SENSOR_ID_NEGATIVE;
+                }
             }
         } else {
             return ConfigStatus.IS_NULL;
@@ -150,11 +162,21 @@ public abstract class BaseSensorHandler extends BaseThingHandler {
     }
 
     protected void dataUpdate() {
-        HTTPHandler.getHandler().request(config.sensorid, this);
+        if (sensorUrl.isPresent()) {
+            HTTPHandler.getHandler().request(sensorUrl.get(), this);
+        }
     }
 
     public void onResponse(String data) {
-        lastUpdateStatus = updateChannels(data);
+        if (firstUpdate) {
+            logger.debug("{} delivers {}", sensorUrl.get(), data);
+            firstUpdate = false;
+        }
+        if (configStatus == ConfigStatus.INTERNAL_SENSOR_OK) {
+            lastUpdateStatus = updateChannels("[" + data + "]");
+        } else {
+            lastUpdateStatus = updateChannels(data);
+        }
         statusUpdate(lastUpdateStatus, EMPTY);
     }
 
index a80ec1f03eec95ffb4c8fb73d523a4ce7853c28d..d3417f1a1be27a901e3ce8636bac106ecd3c7936 100644 (file)
@@ -13,7 +13,8 @@
 package org.openhab.binding.luftdateninfo.internal.handler;
 
 import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler.*;
+import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
+import static org.openhab.core.library.unit.MetricPrefix.HECTO;
 
 import java.util.List;
 
@@ -38,11 +39,10 @@ import org.openhab.core.thing.Thing;
  */
 @NonNullByDefault
 public class ConditionHandler extends BaseSensorHandler {
-
     protected QuantityType<Temperature> temperatureCache = QuantityType.valueOf(-1, SIUnits.CELSIUS);
     protected QuantityType<Dimensionless> humidityCache = QuantityType.valueOf(-1, Units.PERCENT);
-    protected QuantityType<Pressure> pressureCache = QuantityType.valueOf(-1, SIUnits.PASCAL);
-    protected QuantityType<Pressure> pressureSeaCache = QuantityType.valueOf(-1, SIUnits.PASCAL);
+    protected QuantityType<Pressure> pressureCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL));
+    protected QuantityType<Pressure> pressureSeaCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL));
 
     public ConditionHandler(Thing thing) {
         super(thing);
@@ -55,18 +55,22 @@ public class ConditionHandler extends BaseSensorHandler {
             if (valueList != null) {
                 if (HTTPHandler.getHandler().isCondition(valueList)) {
                     valueList.forEach(v -> {
-                        if (v.getValueType().equals(TEMPERATURE)) {
+                        if (v.getValueType().endsWith(TEMPERATURE)) {
                             temperatureCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
                                     SIUnits.CELSIUS);
                             updateState(TEMPERATURE_CHANNEL, temperatureCache);
-                        } else if (v.getValueType().equals(HUMIDITY)) {
+                        } else if (v.getValueType().endsWith(HUMIDITY)) {
                             humidityCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.PERCENT);
                             updateState(HUMIDITY_CHANNEL, humidityCache);
-                        } else if (v.getValueType().equals(PRESSURE)) {
-                            pressureCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), SIUnits.PASCAL);
+                        } else if (v.getValueType().endsWith(PRESSURE)) {
+                            pressureCache = QuantityType.valueOf(
+                                    NumberUtils.round(NumberUtils.convert(v.getValue()) / 100, 1),
+                                    HECTO(SIUnits.PASCAL));
                             updateState(PRESSURE_CHANNEL, pressureCache);
-                        } else if (v.getValueType().equals(PRESSURE_SEALEVEL)) {
-                            pressureSeaCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), SIUnits.PASCAL);
+                        } else if (v.getValueType().endsWith(PRESSURE_SEALEVEL)) {
+                            pressureSeaCache = QuantityType.valueOf(
+                                    NumberUtils.round(NumberUtils.convert(v.getValue()) / 100, 1),
+                                    HECTO(SIUnits.PASCAL));
                             updateState(PRESSURE_SEA_CHANNEL, pressureSeaCache);
                         }
                     });
index ec47aa212d63da4a47b3300c15a91ddc969c1213..050b69c3d8043cf1213785b8799d3a24c1634e18 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.luftdateninfo.internal.handler;
 
+import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
+
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Objects;
@@ -42,19 +44,6 @@ public class HTTPHandler {
     private static final Gson GSON = new Gson();
     private static final HTTPHandler HTTP_HANDLER = new HTTPHandler();
 
-    public static final String P1 = "P1";
-    public static final String P2 = "P2";
-
-    public static final String TEMPERATURE = "temperature";
-    public static final String HUMIDITY = "humidity";
-    public static final String PRESSURE = "pressure";
-    public static final String PRESSURE_SEALEVEL = "pressure_at_sealevel";
-
-    public static final String NOISE_EQ = "noise_LAeq";
-    public static final String NOISE_MIN = "noise_LA_min";
-    public static final String NOISE_MAX = "noise_LA_max";
-
-    private static String sensorUrl = "http://data.sensor.community/airrohr/v1/sensor/";
     private static @Nullable HttpClient commonHttpClient;
 
     public static void init(HttpClient httpClient) {
@@ -65,12 +54,11 @@ public class HTTPHandler {
         return HTTP_HANDLER;
     }
 
-    public synchronized void request(int sensorId, BaseSensorHandler callback) {
+    public synchronized void request(String url, BaseSensorHandler callback) {
         HttpClient localClient = commonHttpClient;
         if (localClient == null) {
             logger.warn("HTTP Client not initialized");
         } else {
-            String url = sensorUrl + sensorId + "/";
             Request req = localClient.newRequest(url);
             req.timeout(15, TimeUnit.SECONDS).send(new BufferingResponseListener() {
                 @NonNullByDefault({})
@@ -142,7 +130,7 @@ public class HTTPHandler {
         if (valueList == null) {
             return false;
         }
-        return valueList.stream().map(v -> v.getValueType()).filter(t -> t.equals(P1) || t.equals(P2)).findAny()
+        return valueList.stream().map(v -> v.getValueType()).filter(t -> t.endsWith(P1) || t.endsWith(P2)).findAny()
                 .isPresent();
     }
 
@@ -150,9 +138,8 @@ public class HTTPHandler {
         if (valueList == null) {
             return false;
         }
-        return valueList.stream().map(v -> v.getValueType()).filter(
-                t -> t.equals(TEMPERATURE) || t.equals(HUMIDITY) || t.equals(PRESSURE) || t.equals(PRESSURE_SEALEVEL))
-                .findAny().isPresent();
+        return valueList.stream().map(v -> v.getValueType()).filter(t -> t.equals(TEMPERATURE) || t.endsWith(HUMIDITY)
+                || t.endsWith(PRESSURE) || t.endsWith(PRESSURE_SEALEVEL)).findAny().isPresent();
     }
 
     public boolean isNoise(@Nullable List<SensorDataValue> valueList) {
@@ -160,6 +147,7 @@ public class HTTPHandler {
             return false;
         }
         return valueList.stream().map(v -> v.getValueType())
-                .filter(t -> t.equals(NOISE_EQ) || t.equals(NOISE_MAX) || t.equals(NOISE_MIN)).findAny().isPresent();
+                .filter(t -> t.endsWith(NOISE_EQ) || t.endsWith(NOISE_MAX) || t.endsWith(NOISE_MIN)).findAny()
+                .isPresent();
     }
 }
index 130bc0b8528336f08e936c64d0ac03233ee2c19b..9a984bed8ddce8c0fae276b86855cb596d2a7067 100644 (file)
@@ -13,7 +13,7 @@
 package org.openhab.binding.luftdateninfo.internal.handler;
 
 import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler.*;
+import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
 
 import java.util.List;
 
@@ -50,13 +50,13 @@ public class NoiseHandler extends BaseSensorHandler {
             if (valueList != null) {
                 if (HTTPHandler.getHandler().isNoise(valueList)) {
                     valueList.forEach(v -> {
-                        if (v.getValueType().equals(NOISE_EQ)) {
+                        if (v.getValueType().endsWith(NOISE_EQ)) {
                             noiseEQCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
                             updateState(NOISE_EQ_CHANNEL, noiseEQCache);
-                        } else if (v.getValueType().equals(NOISE_MIN)) {
+                        } else if (v.getValueType().endsWith(NOISE_MIN)) {
                             noiseMinCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
                             updateState(NOISE_MIN_CHANNEL, noiseMinCache);
-                        } else if (v.getValueType().equals(NOISE_MAX)) {
+                        } else if (v.getValueType().endsWith(NOISE_MAX)) {
                             noiseMaxCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
                             updateState(NOISE_MAX_CHANNEL, noiseMaxCache);
                         }
index 55dcfb16e15d16f9748c59c33b492993307ac621..7ddd4e43ab882e9b4fe9dbf0a49102ef333078dd 100644 (file)
@@ -13,7 +13,7 @@
 package org.openhab.binding.luftdateninfo.internal.handler;
 
 import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler.*;
+import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
 
 import java.util.List;
 
@@ -49,11 +49,11 @@ public class PMHandler extends BaseSensorHandler {
             if (valueList != null) {
                 if (HTTPHandler.getHandler().isParticulate(valueList)) {
                     valueList.forEach(v -> {
-                        if (v.getValueType().equals(P1)) {
+                        if (v.getValueType().endsWith(P1)) {
                             pm100Cache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
                                     Units.MICROGRAM_PER_CUBICMETRE);
                             updateState(PM100_CHANNEL, pm100Cache);
-                        } else if (v.getValueType().equals(P2)) {
+                        } else if (v.getValueType().endsWith(P2)) {
                             pm25Cache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
                                     Units.MICROGRAM_PER_CUBICMETRE);
                             updateState(PM25_CHANNEL, pm25Cache);
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/Constants.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/Constants.java
new file mode 100644 (file)
index 0000000..18b1e77
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * 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.binding.luftdateninfo.internal.utils;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link Constants} Constants used in this binding
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class Constants {
+    public static final String EMPTY = "";
+    public static final String P1 = "P1";
+    public static final String P2 = "P2";
+
+    public static final String TEMPERATURE = "temperature";
+    public static final String HUMIDITY = "humidity";
+    public static final String PRESSURE = "pressure";
+    public static final String PRESSURE_SEALEVEL = "pressure_at_sealevel";
+
+    public static final String NOISE_EQ = "noise_LAeq";
+    public static final String NOISE_MIN = "noise_LA_min";
+    public static final String NOISE_MAX = "noise_LA_max";
+    public static final int UNDEF = -1;
+}
index abe42dc4b202de57c8ebcaf1a6f273a95455bcf0..001a2c1cb93f8489bb71557ecaff01184e8a8b1a 100644 (file)
                </channels>
 
                <config-description>
-                       <parameter name="sensorid" type="integer" required="true">
-                               <label>Sensor ID</label>
-                               <description>Sensor ID</description>
+                       <parameter name="ipAddress" type="text">
+                               <context>network-address</context>
+                               <label>Internal IP Address</label>
+                               <description>Local IP address of your personal owned sensor</description>
+                       </parameter>
+                       <parameter name="sensorid" type="integer">
+                               <label>External Sensor ID</label>
+                               <description>Sensor ID from https://deutschland.maps.sensor.community/</description>
                        </parameter>
                </config-description>
        </thing-type>
                </channels>
 
                <config-description>
-                       <parameter name="sensorid" type="integer" required="true">
-                               <label>Sensor ID</label>
-                               <description>Sensor ID</description>
+                       <parameter name="ipAddress" type="text">
+                               <context>network-address</context>
+                               <label>Internal IP Address</label>
+                               <description>Local IP address of your personal owned sensor</description>
+                       </parameter>
+                       <parameter name="sensorid" type="integer">
+                               <label>External Sensor ID</label>
+                               <description>Sensor ID from https://deutschland.maps.sensor.community/</description>
                        </parameter>
                </config-description>
        </thing-type>
                </channels>
 
                <config-description>
-                       <parameter name="sensorid" type="integer" required="true">
-                               <label>Sensor ID</label>
-                               <description>Sensor ID</description>
+                       <parameter name="ipAddress" type="text">
+                               <context>network-address</context>
+                               <label>Internal IP Address</label>
+                               <description>Local IP address of your personal owned sensor</description>
+                       </parameter>
+                       <parameter name="sensorid" type="integer">
+                               <label>External Sensor ID</label>
+                               <description>Sensor ID from https://deutschland.maps.sensor.community/</description>
                        </parameter>
                </config-description>
        </thing-type>
        <channel-type id="pm25-channel">
                <item-type>Number:Density</item-type>
                <label>Particulate Matter category 2.5</label>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="pm100-channel">
                <item-type>Number:Density</item-type>
                <label>Particulate Matter category 10.0</label>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="temp-channel">
                <item-type>Number:Temperature</item-type>
                <label>Temperature</label>
                <description>Temperature from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="hum-channel">
                <item-type>Number:Dimensionless</item-type>
                <label>Humidity</label>
                <description>Humidity from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="pressure-channel">
                <item-type>Number:Pressure</item-type>
                <label>Atmospheric Pressure</label>
                <description>Atmospheric Pressure from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="pressure-sea-channel">
                <item-type>Number:Pressure</item-type>
                <label>Atmospheric Pressure Sea Level</label>
                <description>Atmospheric Pressure at sea level from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="noise-eq-channel">
                <item-type>Number:Dimensionless</item-type>
                <label>Average Noise</label>
                <description>Average noise level from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="noise-min-channel">
                <item-type>Number:Dimensionless</item-type>
                <label>Minimum Noise</label>
                <description>Minimum noise level (last 2.5 minutes) from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
        <channel-type id="noise-max-channel">
                <item-type>Number:Dimensionless</item-type>
                <label>Maximum Noise</label>
                <description>Maximum noise level (last 2.5 minutes) from the selected Sensor ID</description>
+               <state pattern="%.1f %unit%" readOnly="true"/>
        </channel-type>
 </thing:thing-descriptions>
index 97eb43a5612b750c25500e05ba448d75e7cf6a57..bf04225f28556463cb3227052752e95b806ce3a3 100644 (file)
@@ -13,6 +13,7 @@
 package org.openhab.binding.luftdateninfo.internal;
 
 import static org.junit.jupiter.api.Assertions.*;
+import static org.openhab.core.library.unit.MetricPrefix.HECTO;
 
 import java.util.HashMap;
 
@@ -49,9 +50,9 @@ public class ConditionHandlerTest {
             UpdateStatus result = condHandler.updateChannels(pmJson);
             assertEquals(UpdateStatus.OK, result, "Valid update");
             assertEquals(QuantityType.valueOf(22.7, SIUnits.CELSIUS), condHandler.getTemperature(), "Temperature");
-            assertEquals(QuantityType.valueOf(61.0, Units.PERCENT), condHandler.getHumidity(), "Humidity");
-            assertEquals(QuantityType.valueOf(-1, SIUnits.PASCAL), condHandler.getPressure(), "Pressure");
-            assertEquals(QuantityType.valueOf(-1, SIUnits.PASCAL), condHandler.getPressureSea(), "Pressure Sea");
+            assertEquals(QuantityType.valueOf(61., Units.PERCENT), condHandler.getHumidity(), "Humidity");
+            assertEquals(QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)), condHandler.getPressure(), "Pressure");
+            assertEquals(QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)), condHandler.getPressureSea(), "Pressure Sea");
         } else {
             assertTrue(false);
         }
@@ -73,8 +74,9 @@ public class ConditionHandlerTest {
             assertEquals(UpdateStatus.OK, result, "Valid update");
             assertEquals(QuantityType.valueOf(21.5, SIUnits.CELSIUS), condHandler.getTemperature(), "Temperature");
             assertEquals(QuantityType.valueOf(58.5, Units.PERCENT), condHandler.getHumidity(), "Humidity");
-            assertEquals(QuantityType.valueOf(100200.0, SIUnits.PASCAL), condHandler.getPressure(), "Pressure");
-            assertEquals(QuantityType.valueOf(101968.7, SIUnits.PASCAL), condHandler.getPressureSea(), "Pressure Sea");
+            assertEquals(QuantityType.valueOf(1002.0, HECTO(SIUnits.PASCAL)), condHandler.getPressure(), "Pressure");
+            assertEquals(QuantityType.valueOf(1019.7, HECTO(SIUnits.PASCAL)), condHandler.getPressureSea(),
+                    "Pressure Sea");
         } else {
             assertTrue(false);
         }
@@ -126,4 +128,27 @@ public class ConditionHandlerTest {
         UpdateStatus result = condHandler.updateChannels(null);
         assertEquals(UpdateStatus.CONNECTION_ERROR, result, "Valid update");
     }
+
+    @Test
+    public void testInternalUpdate() {
+        ThingMock t = new ThingMock();
+
+        HashMap<String, Object> properties = new HashMap<String, Object>();
+        // String sensorid taken from thing-types.xml
+        properties.put("ipAddress", "192.168.178.1");
+        t.setConfiguration(properties);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/internal-data.json");
+        if (pmJson != null) {
+            UpdateStatus result = condHandler.updateChannels("[" + pmJson + "]");
+            assertEquals(UpdateStatus.OK, result, "Valid update");
+            assertEquals(QuantityType.valueOf(17.6, SIUnits.CELSIUS), condHandler.getTemperature(), "Temperature");
+            assertEquals(QuantityType.valueOf(57.8, Units.PERCENT), condHandler.getHumidity(), "Humidity");
+            assertEquals(QuantityType.valueOf(986.8, HECTO(SIUnits.PASCAL)), condHandler.getPressure(), "Pressure");
+            assertEquals(QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)), condHandler.getPressureSea(), "Pressure Sea");
+        } else {
+            assertTrue(false);
+        }
+    }
 }
index 07ad76d65bf6132dfea5bb8f4ff62315aaea5a38..93355b0414776ef48e9baba996abac48e441a53d 100644 (file)
@@ -20,8 +20,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.junit.jupiter.api.Test;
 import org.openhab.binding.luftdateninfo.internal.dto.SensorData;
 import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
-import org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler;
 import org.openhab.binding.luftdateninfo.internal.util.FileReader;
+import org.openhab.binding.luftdateninfo.internal.utils.Constants;
 
 import com.google.gson.Gson;
 
@@ -44,16 +44,16 @@ public class DTOTest {
         SensorData d = valueArray[0];
         // Assure latest data is taken
         String dateStr = d.getTimeStamp();
-        if (dateStr.equals("2020-06-09 06:38:08")) {
+        if ("2020-06-09 06:38:08".equals(dateStr)) {
             // take newer one
             d = valueArray[1];
         }
         List<SensorDataValue> sensorDataVaueList = d.getSensorDataValues();
         assertNotNull(d);
         sensorDataVaueList.forEach(v -> {
-            if (v.getValueType().equals(HTTPHandler.TEMPERATURE)) {
+            if (Constants.TEMPERATURE.equals(v.getValueType())) {
                 assertEquals("22.70", v.getValue(), "Temperature");
-            } else if (v.getValueType().equals(HTTPHandler.HUMIDITY)) {
+            } else if (Constants.HUMIDITY.equals(v.getValueType())) {
                 assertEquals("61.00", v.getValue(), "Humidity");
             }
         });
index faaf90ef36528ba5f16c70802d9e39b5dfb308b0..ac4192cb06f156c868133af216379cc375410dea 100644 (file)
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
 import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
 import org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler;
 import org.openhab.binding.luftdateninfo.internal.util.FileReader;
+import org.openhab.binding.luftdateninfo.internal.utils.Constants;
 
 /**
  * The {@link HTTPHandlerValueTest} test values decoding of HTTPHandler
@@ -61,9 +62,9 @@ public class HTTPHandlerValueTest {
     }
 
     private void testSensorValue(SensorDataValue s) {
-        if (s.getValueType().equals(HTTPHandler.TEMPERATURE)) {
+        if (s.getValueType().equals(Constants.TEMPERATURE)) {
             assertEquals("22.70", s.getValue(), "Temperature resource 1");
-        } else if (s.getValueType().equals(HTTPHandler.HUMIDITY)) {
+        } else if (s.getValueType().equals(Constants.HUMIDITY)) {
             assertEquals("61.00", s.getValue(), "Humidity resource 1");
         } else {
             assertTrue(false);
index 3923dff4024bb7397b72da68ec278a47af95c75a..d30183b4e797b1a781e361c34e19b258aff3a059 100644 (file)
@@ -64,7 +64,7 @@ public class PMHandlerTest {
          * Test if config status is 0 = CONFIG_OK for valid configuration. Take real int for comparison instead of
          * BaseHandler constants - in case of change test needs to be adapted
          */
-        assertEquals(ConfigStatus.OK, pmHandler.getConfigStatus(), "Handler Configuration status");
+        assertEquals(ConfigStatus.EXTERNAL_SENSOR_OK, pmHandler.getConfigStatus(), "Handler Configuration status");
     }
 
     @Test
@@ -161,11 +161,34 @@ public class PMHandlerTest {
 
         HashMap<String, Object> properties = new HashMap<String, Object>();
         // String sensorid taken from thing-types.xml
-        properties.put("sensorid", 12345);
+        properties.put("ipAdress", "192.168.178.1");
         t.setConfiguration(properties);
 
         PMHandlerExtension pmHandler = new PMHandlerExtension(t);
         UpdateStatus result = pmHandler.updateChannels(null);
         assertEquals(UpdateStatus.CONNECTION_ERROR, result, "Valid update");
     }
+
+    @Test
+    public void testInternalPMSensor() {
+        ThingMock t = new ThingMock();
+
+        HashMap<String, Object> properties = new HashMap<String, Object>();
+        // String sensorid taken from thing-types.xml
+        properties.put("sensorid", 12345);
+        t.setConfiguration(properties);
+
+        PMHandlerExtension pmHandler = new PMHandlerExtension(t);
+        pmHandler.initialize();
+        String pmJson = FileReader.readFileInString("src/test/resources/internal-data.json");
+        if (pmJson != null) {
+            UpdateStatus result = pmHandler.updateChannels("[" + pmJson + "]");
+            assertEquals(UpdateStatus.OK, result, "Valid update");
+            assertEquals(QuantityType.valueOf(4.3, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM25Cache(), "PM25");
+            assertEquals(QuantityType.valueOf(10.5, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM100Cache(),
+                    "PM100");
+        } else {
+            assertTrue(false);
+        }
+    }
 }
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/internal-data.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/internal-data.json
new file mode 100644 (file)
index 0000000..04d75b4
--- /dev/null
@@ -0,0 +1,46 @@
+{
+       "software_version": "NRZ-2020-133",
+       "age": "112",
+       "sensordatavalues": [
+               {
+                       "value_type": "SDS_P1",
+                       "value": "10.52"
+               },
+               {
+                       "value_type": "SDS_P2",
+                       "value": "4.32"
+               },
+               {
+                       "value_type": "BME280_temperature",
+                       "value": "17.59"
+               },
+               {
+                       "value_type": "BME280_pressure",
+                       "value": "98680.28"
+               },
+               {
+                       "value_type": "BME280_humidity",
+                       "value": "57.78"
+               },
+               {
+                       "value_type": "samples",
+                       "value": "5070500"
+               },
+               {
+                       "value_type": "min_micro",
+                       "value": "28"
+               },
+               {
+                       "value_type": "max_micro",
+                       "value": "20091"
+               },
+               {
+                       "value_type": "interval",
+                       "value": "145000"
+               },
+               {
+                       "value_type": "signal",
+                       "value": "-81"
+               }
+       ]
+}
\ No newline at end of file