]> git.basschouten.com Git - openhab-addons.git/commitdiff
[luftdateninfo][sensorcommunity] Rename binding to Sensor.Community (#15012)
authorHolger Friedrich <holgerfriedrich@users.noreply.github.com>
Mon, 22 May 2023 05:57:23 +0000 (07:57 +0200)
committerGitHub <noreply@github.com>
Mon, 22 May 2023 05:57:23 +0000 (07:57 +0200)
* [luftdateninfo][sensorcommunity] Rename binding to match the new name Sensor.Community

Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
93 files changed:
CODEOWNERS
bom/openhab-addons/pom.xml
bundles/org.openhab.binding.luftdateninfo/NOTICE [deleted file]
bundles/org.openhab.binding.luftdateninfo/README.md [deleted file]
bundles/org.openhab.binding.luftdateninfo/doc/LuftdatenInfo-Map.png [deleted file]
bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png [deleted file]
bundles/org.openhab.binding.luftdateninfo/pom.xml [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/feature/feature.xml [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoBindingConstants.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoConfiguration.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoHandlerFactory.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Location.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Sensor.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorData.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorDataValue.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorType.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/BaseSensorHandler.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/ConditionHandler.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/HTTPHandler.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/NoiseHandler.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/PMHandler.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/Constants.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/DateTimeUtils.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/NumberUtils.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/addon/addon.xml [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo.properties [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo_de.properties [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/thing/thing-types.xml [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/ConditionHandlerTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/DTOTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerEvalTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerValueTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NoiseHandlerTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NumberTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/PMHandlerTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ConditionHandlerExtension.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/NoiseHandlerExtension.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/PMHandlerExtension.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ThingMock.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/DateTimeTest.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/FileReader.java [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure-flipped-values.json [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure.json [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-plus-pressure.json [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/internal-data.json [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/noise-result.json [deleted file]
bundles/org.openhab.binding.luftdateninfo/src/test/resources/pm-result.json [deleted file]
bundles/org.openhab.binding.sensorcommunity/NOTICE [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/README.md [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/doc/SensorCommunity-Map.png [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/doc/local-sensor.png [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/pom.xml [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/feature/feature.xml [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityBindingConstants.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityConfiguration.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityHandlerFactory.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Location.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Sensor.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorData.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorDataValue.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorType.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/BaseSensorHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/ConditionHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/HTTPHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/NoiseHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/PMHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/Constants.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/DateTimeUtils.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/NumberUtils.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/addon/addon.xml [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity.properties [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity_de.properties [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/thing/thing-types.xml [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/ConditionHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/DTOTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerEvalTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerValueTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NoiseHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NumberTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/PMHandlerTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ConditionHandlerExtension.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/NoiseHandlerExtension.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/PMHandlerExtension.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ThingMock.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/DateTimeTest.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/FileReader.java [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure-flipped-values.json [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure.json [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-plus-pressure.json [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/internal-data.json [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/noise-result.json [new file with mode: 0644]
bundles/org.openhab.binding.sensorcommunity/src/test/resources/pm-result.json [new file with mode: 0644]
bundles/pom.xml

index 210ce9a6241249245c122a327a3df94e10a804b9..8339cf8b62aae4e3963da735aee3678b4e94ef5b 100644 (file)
 /bundles/org.openhab.binding.livisismarthome/ @Novanic
 /bundles/org.openhab.binding.logreader/ @paulianttila
 /bundles/org.openhab.binding.loxone/ @ppieczul
-/bundles/org.openhab.binding.luftdateninfo/ @weymann
 /bundles/org.openhab.binding.lutron/ @actong @bobadair
 /bundles/org.openhab.binding.luxom/ @jesperskriasoft
 /bundles/org.openhab.binding.luxtronikheatpump/ @sgiehl
 /bundles/org.openhab.binding.seneye/ @nikotanghe
 /bundles/org.openhab.binding.sensebox/ @hakan42
 /bundles/org.openhab.binding.sensibo/ @seime
+/bundles/org.openhab.binding.sensorcommunity/ @weymann
 /bundles/org.openhab.binding.serial/ @MikeJMajor
 /bundles/org.openhab.binding.serialbutton/ @kaikreuzer
 /bundles/org.openhab.binding.shelly/ @markus7017
index 420d5cd44473b8d273705e700a29be6b569f5a27..6e84ed35d369afb8e38532136a9faa1dd8604c88 100644 (file)
       <artifactId>org.openhab.binding.loxone</artifactId>
       <version>${project.version}</version>
     </dependency>
-    <dependency>
-      <groupId>org.openhab.addons.bundles</groupId>
-      <artifactId>org.openhab.binding.luftdateninfo</artifactId>
-      <version>${project.version}</version>
-    </dependency>
     <dependency>
       <groupId>org.openhab.addons.bundles</groupId>
       <artifactId>org.openhab.binding.lutron</artifactId>
       <artifactId>org.openhab.binding.sensibo</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.openhab.addons.bundles</groupId>
+      <artifactId>org.openhab.binding.sensorcommunity</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.openhab.addons.bundles</groupId>
       <artifactId>org.openhab.binding.serial</artifactId>
diff --git a/bundles/org.openhab.binding.luftdateninfo/NOTICE b/bundles/org.openhab.binding.luftdateninfo/NOTICE
deleted file mode 100644 (file)
index 38d625e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-This content is produced and maintained by the openHAB project.
-
-* Project home: https://www.openhab.org
-
-== Declared Project Licenses
-
-This program and the accompanying materials are made available under the terms
-of the Eclipse Public License 2.0 which is available at
-https://www.eclipse.org/legal/epl-2.0/.
-
-== Source Code
-
-https://github.com/openhab/openhab-addons
diff --git a/bundles/org.openhab.binding.luftdateninfo/README.md b/bundles/org.openhab.binding.luftdateninfo/README.md
deleted file mode 100644 (file)
index 9cb7bce..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-# LuftdatenInfo Binding
-
-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.
-
-## Supported Things
-
-Three Things are supported
-
-| Name               | Thing Type ID | Description                                                                                            |
-|--------------------|---------------|--------------------------------------------------------------------------------------------------------|
-| Particulate Sensor | particulate   | measure particulate matter PM2.5 and PM10                                                              |
-| Conditions Sensor  | condition     | measures environment conditions like temperature, humidity and some also provides atmospheric pressure |
-| Noise Sensor       | noise         | measures noise exposures in the environment                                                            |
-
-## Discovery
-
-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/)
-- Choose your desired value in bottom list - now only the Sensors are displayed which are supporting this
-- Click on your / any Sensor and the ID is displayed in the top right corner. Note: Sensor ID is just the number without beginning hash #
-- Enter this Sensor ID into the thing configuration
-
-![Luftdaten.info Logo](doc/LuftdatenInfo-Map.png)
-
-## Channels
-
-### Particulate Sensor
-
-| Channel ID           | Item Type            | Description                              |
-|----------------------|----------------------|------------------------------------------|
-| pm25                 | Number:Density       | [Ultrafine particulates](https://en.wikipedia.org/wiki/Particulates#Size,_shape_and_solubility_matter) microgram per cubic meter |
-| pm100                | Number:Density       | [Coarse particulate matter](https://en.wikipedia.org/wiki/Particulates#Size,_shape_and_solubility_matter) microgram per cubic meter  |
-
-### Conditions Sensor
-
-| Channel ID           | Item Type            | Description                              |
-|----------------------|----------------------|------------------------------------------|
-| temperature          | Number:Temperature   | current temperature                      |
-| humidity             | Number:Dimensionless | current humidity percent                 |
-| pressure             | Number:Pressure      | Atmospheric Pressure (not supported by all sensors) |
-| pressure-sea         | Number:Pressure      | Atmospheric Pressure on sea level (not supported by all sensors)  |
-
-### Noise Sensor
-
-| Channel ID           | Item Type            | Description                                          |
-|----------------------|----------------------|------------------------------------------------------|
-| noise-eq             | Number:Dimensionless | Average noise in db                                  |
-| noise-min            | Number:Dimensionless | Minimum noise covered in the last 2.5 minutes in db  |
-| noise-main           | Number:Dimensionless | Maximum noise covered in the last 2.5 minutes in db  |
-
-## Full Example
-
-### Things
-
-luftdaten.things
-
-```java
-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
-
-luftdaten.items
-
-```java
-Number:Density PM_25                "PM2.5"                 { channel="luftdateninfo:particulate:pm_sensor:pm25" } 
-Number:Density PM_100               "PM10"                  { channel="luftdateninfo:particulate:pm_sensor:pm100" } 
-
-Number:Temperature LDI_Temperature  "Temperature"           { channel="luftdateninfo:conditions:cond_sensor:temperature" } 
-Number:Dimensionless LDI_Humidity   "Humidity"              { channel="luftdateninfo:conditions:cond_sensor:humidity" } 
-Number:Pressure LDI_Pressure        "Atmospheric Pressure"  { channel="luftdateninfo:conditions:cond_sensor:pressure" } 
-Number:Pressure LDI_PressureSea     "Pressure sea level"    { channel="luftdateninfo:conditions:cond_sensor:pressure-sea" } 
-
-Number:Dimensionless LDI_NoiseEQ    "Noise EQ"              { channel="luftdateninfo:noise:noise_sensor:noise-eq" } 
-Number:Dimensionless LDI_NoiseMin   "Noise min"             { channel="luftdateninfo:noise:noise_sensor:noise-min" } 
-Number:Dimensionless LDI_NoiseMax   "Noise max"             { channel="luftdateninfo:noise:noise_sensor:noise-max" } 
-```
-
-### Sitemap
-
-LuftdatenInfo.sitemap
-
-```perl
-sitemap LuftdatenInfo label="LuftdatenInfo" {
-        Text item=PM_25                     label="Particulate Matter 2.5 [%.1f %unit%]"    
-        Text item=PM_100                    label="Particulate Matter 10 [%.1f %unit%]"     
-
-        Text item=LDI_Temperature           label="Temperature [%d %unit%]"     
-        Text item=LDI_Humidity              label="Humidity [%d %unit%]"    
-        Text item=LDI_Pressure              label="Atmospheric Pressure [%d %unit%]"    
-        Text item=LDI_PressureSea           label="Atmospheric Pressure sea [%d %unit%]"    
-                                            
-        Text item=LDI_NoiseEQ               label="Noise avg [%.1f %unit%]"     
-        Text item=LDI_NoiseMin              label="Noise min [%.1f %unit%]"     
-        Text item=LDI_NoiseMax              label="Noise max [%.1f %unit%]"     
-}
-```
diff --git a/bundles/org.openhab.binding.luftdateninfo/doc/LuftdatenInfo-Map.png b/bundles/org.openhab.binding.luftdateninfo/doc/LuftdatenInfo-Map.png
deleted file mode 100644 (file)
index faa378d..0000000
Binary files a/bundles/org.openhab.binding.luftdateninfo/doc/LuftdatenInfo-Map.png and /dev/null differ
diff --git a/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png b/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png
deleted file mode 100644 (file)
index ccf4e6f..0000000
Binary files a/bundles/org.openhab.binding.luftdateninfo/doc/local-sensor.png and /dev/null differ
diff --git a/bundles/org.openhab.binding.luftdateninfo/pom.xml b/bundles/org.openhab.binding.luftdateninfo/pom.xml
deleted file mode 100644 (file)
index 660668e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.openhab.addons.bundles</groupId>
-    <artifactId>org.openhab.addons.reactor.bundles</artifactId>
-    <version>4.0.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>org.openhab.binding.luftdateninfo</artifactId>
-
-  <name>openHAB Add-ons :: Bundles :: LuftdatenInfo Binding</name>
-
-</project>
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/feature/feature.xml b/bundles/org.openhab.binding.luftdateninfo/src/main/feature/feature.xml
deleted file mode 100644 (file)
index 0c844e7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<features name="org.openhab.binding.luftdateninfo-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
-       <repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
-
-       <feature name="openhab-binding-luftdateninfo" description="LuftdatenInfo Binding" version="${project.version}">
-               <feature>openhab-runtime-base</feature>
-               <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.luftdateninfo/${project.version}</bundle>
-       </feature>
-</features>
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoBindingConstants.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoBindingConstants.java
deleted file mode 100644 (file)
index d594b42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.core.thing.ThingTypeUID;
-
-/**
- * The {@link LuftdatenInfoBindingConstants} class defines common constants, which are
- * used across the whole binding.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class LuftdatenInfoBindingConstants {
-
-    private static final String BINDING_ID = "luftdateninfo";
-
-    // List of all Thing Type UIDs
-    public static final ThingTypeUID THING_TYPE_PARTICULATE = new ThingTypeUID(BINDING_ID, "particulate");
-    public static final ThingTypeUID THING_TYPE_CONDITIONS = new ThingTypeUID(BINDING_ID, "conditions");
-    public static final ThingTypeUID THING_TYPE_NOISE = new ThingTypeUID(BINDING_ID, "noise");
-
-    // List of all Channel ids
-    public static final String PM25_CHANNEL = "pm25";
-    public static final String PM100_CHANNEL = "pm100";
-    public static final String TEMPERATURE_CHANNEL = "temperature";
-    public static final String HUMIDITY_CHANNEL = "humidity";
-    public static final String PRESSURE_CHANNEL = "pressure";
-    public static final String PRESSURE_SEA_CHANNEL = "pressure-sea";
-    public static final String NOISE_EQ_CHANNEL = "noise-eq";
-    public static final String NOISE_MIN_CHANNEL = "noise-min";
-    public static final String NOISE_MAX_CHANNEL = "noise-max";
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoConfiguration.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoConfiguration.java
deleted file mode 100644 (file)
index d3cc4eb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.luftdateninfo.internal.utils.Constants;
-
-/**
- * The {@link LuftdatenInfoConfiguration} class contains fields mapping thing configuration parameters.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class LuftdatenInfoConfiguration {
-
-    public int sensorid = Constants.UNDEF;
-
-    public String ipAddress = Constants.EMPTY;
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoHandlerFactory.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoHandlerFactory.java
deleted file mode 100644 (file)
index 42ff36a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.handler.ConditionHandler;
-import org.openhab.binding.luftdateninfo.internal.handler.HTTPHandler;
-import org.openhab.binding.luftdateninfo.internal.handler.NoiseHandler;
-import org.openhab.binding.luftdateninfo.internal.handler.PMHandler;
-import org.openhab.core.io.net.http.HttpClientFactory;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingTypeUID;
-import org.openhab.core.thing.binding.BaseThingHandlerFactory;
-import org.openhab.core.thing.binding.ThingHandler;
-import org.openhab.core.thing.binding.ThingHandlerFactory;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link LuftdatenInfoHandlerFactory} is responsible for creating things and thing
- * handlers.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-@Component(configurationPid = "binding.luftdateninfo", service = ThingHandlerFactory.class)
-public class LuftdatenInfoHandlerFactory extends BaseThingHandlerFactory {
-    protected final Logger logger = LoggerFactory.getLogger(LuftdatenInfoHandlerFactory.class);
-
-    @Activate
-    public LuftdatenInfoHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
-        HTTPHandler.init(httpClientFactory.getCommonHttpClient());
-    }
-
-    @Override
-    public boolean supportsThingType(ThingTypeUID thingTypeUID) {
-        return (thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_PARTICULATE)
-                || thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_CONDITIONS)
-                || thingTypeUID.equals(LuftdatenInfoBindingConstants.THING_TYPE_NOISE));
-    }
-
-    @Override
-    protected @Nullable ThingHandler createHandler(Thing thing) {
-        if (thing.getThingTypeUID().equals(LuftdatenInfoBindingConstants.THING_TYPE_PARTICULATE)) {
-            return new PMHandler(thing);
-        } else if (thing.getThingTypeUID().equals(LuftdatenInfoBindingConstants.THING_TYPE_CONDITIONS)) {
-            return new ConditionHandler(thing);
-        } else if (thing.getThingTypeUID().equals(LuftdatenInfoBindingConstants.THING_TYPE_NOISE)) {
-            return new NoiseHandler(thing);
-        }
-        logger.info("Handler for {} not found", thing.getThingTypeUID());
-        return null;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Location.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Location.java
deleted file mode 100644 (file)
index ddd03d1..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.dto;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link LuftdatenInfo} class definition for Logging identification
- *
- * @author Bernd Weymann - Initial contribution
- */
-public class Location {
-    private int id;
-    private String country;
-    private String altitude;
-    private String latitude;
-    private String longitude;
-    private int indoor;
-    @SerializedName("exact_location")
-    private int exactLocation;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getCountry() {
-        return country;
-    }
-
-    public void setCountry(String country) {
-        this.country = country;
-    }
-
-    public String getAltitude() {
-        return altitude;
-    }
-
-    public void setAltitude(String altitude) {
-        this.altitude = altitude;
-    }
-
-    public String getLatitude() {
-        return latitude;
-    }
-
-    public void setLatitude(String latitude) {
-        this.latitude = latitude;
-    }
-
-    public String getLongitude() {
-        return longitude;
-    }
-
-    public void setLongitude(String longitude) {
-        this.longitude = longitude;
-    }
-
-    public Integer getIndoor() {
-        return indoor;
-    }
-
-    public void setIndoor(int indoor) {
-        this.indoor = indoor;
-    }
-
-    public int getExactLocation() {
-        return exactLocation;
-    }
-
-    public void setExactLocation(int exactLocation) {
-        this.exactLocation = exactLocation;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Sensor.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Sensor.java
deleted file mode 100644 (file)
index a8036a8..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.dto;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link Sensor} Data Transfer Object
- *
- * @author Bernd Weymann - Initial contribution
- */
-public class Sensor {
-    private int id;
-    private String pin;
-    @SerializedName("sensor_type")
-    private SensorType sensorType;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getPin() {
-        return pin;
-    }
-
-    public void setPin(String pin) {
-        this.pin = pin;
-    }
-
-    public SensorType getSensoTypee() {
-        return sensorType;
-    }
-
-    public void setSensorType(SensorType sensorType) {
-        this.sensorType = sensorType;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorData.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorData.java
deleted file mode 100644 (file)
index 4c340d8..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.dto;
-
-import java.util.List;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link SensorData} Data Transfer Object
- *
- * @author Bernd Weymann - Initial contribution
- */
-public class SensorData {
-    private long id;
-    private String timestamp;
-    @SerializedName("sampling_rate")
-    private int samplingRate;
-    @SerializedName("sensordatavalues")
-    private List<SensorDataValue> sensorDataValues;
-    private Location location;
-    private Sensor sensor;
-
-    @Override
-    public String toString() {
-        return id + timestamp;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getTimeStamp() {
-        return timestamp;
-    }
-
-    public void setTimeStamp(String timeStamp) {
-        this.timestamp = timeStamp;
-    }
-
-    public int getSamplingRate() {
-        return samplingRate;
-    }
-
-    public void setSamplingRate(int samplingRate) {
-        this.samplingRate = samplingRate;
-    }
-
-    public List<SensorDataValue> getSensorDataValues() {
-        return sensorDataValues;
-    }
-
-    public void setSensorDataValues(List<SensorDataValue> sensorDataValues) {
-        this.sensorDataValues = sensorDataValues;
-    }
-
-    public Location getLocation() {
-        return location;
-    }
-
-    public void setLocation(Location location) {
-        this.location = location;
-    }
-
-    public Sensor getSensor() {
-        return sensor;
-    }
-
-    public void setSensor(Sensor sensor) {
-        this.sensor = sensor;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorDataValue.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorDataValue.java
deleted file mode 100644 (file)
index 9a9ec35..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.dto;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link SensorDataValue} Data Transfer Object
- *
- * @author Bernd Weymann - Initial contribution
- */
-public class SensorDataValue {
-    private long id;
-    @SerializedName("value_type")
-    private String valueType;
-    private String value;
-
-    @Override
-    public String toString() {
-        return valueType + ":" + value;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getValueType() {
-        return valueType;
-    }
-
-    public void setValueType(String valueType) {
-        this.valueType = valueType;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorType.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorType.java
deleted file mode 100644 (file)
index 811eb19..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.dto;
-
-/**
- * The {@link SensorType} Data Transfer Object
- *
- * @author Bernd Weymann - Initial contribution
- */
-public class SensorType {
-    private int id;
-    private String manufacturer;
-    private String name;
-
-    public Integer getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getManufacturer() {
-        return manufacturer;
-    }
-
-    public void setManufacturer(String manufacturer) {
-        this.manufacturer = manufacturer;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/BaseSensorHandler.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/BaseSensorHandler.java
deleted file mode 100644 (file)
index 9c6aae3..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.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;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
-import org.openhab.core.thing.binding.BaseThingHandler;
-import org.openhab.core.types.Command;
-import org.openhab.core.types.RefreshType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link PMHandler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public abstract class BaseSensorHandler extends BaseThingHandler {
-    private static final LuftdatenInfoConfiguration DEFAULT_CONFIG = new LuftdatenInfoConfiguration();
-    private static final String EMPTY = "";
-
-    protected static final int REFRESH_INTERVAL_MIN = 5;
-    protected final Logger logger = LoggerFactory.getLogger(BaseSensorHandler.class);
-    protected LuftdatenInfoConfiguration config = DEFAULT_CONFIG;
-    protected ConfigStatus configStatus = ConfigStatus.UNKNOWN;
-    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 {
-        INTERNAL_SENSOR_OK,
-        EXTERNAL_SENSOR_OK,
-        IS_NULL,
-        SENSOR_IS_NULL,
-        SENSOR_ID_NEGATIVE,
-        UNKNOWN
-    };
-
-    public enum UpdateStatus {
-        OK,
-        CONNECTION_ERROR,
-        CONNECTION_EXCEPTION,
-        VALUE_ERROR,
-        VALUE_EMPTY,
-        UNKNOWN
-    }
-
-    protected LifecycleStatus lifecycleStatus = LifecycleStatus.UNKNOWN;
-
-    public enum LifecycleStatus {
-        UNKNOWN,
-        RUNNING,
-        INITIALIZING,
-        DISPOSED
-    }
-
-    public BaseSensorHandler(Thing thing) {
-        super(thing);
-    }
-
-    @Override
-    public void handleCommand(ChannelUID channelUID, Command command) {
-        if (command instanceof RefreshType) {
-            updateFromCache();
-        }
-    }
-
-    @Override
-    public void initialize() {
-        firstUpdate = true;
-        lifecycleStatus = LifecycleStatus.INITIALIZING;
-        scheduler.execute(this::startUp);
-    }
-
-    private void startUp() {
-        config = getConfigAs(LuftdatenInfoConfiguration.class);
-        configStatus = checkConfig(config);
-        if (configStatus == ConfigStatus.INTERNAL_SENSOR_OK || configStatus == ConfigStatus.EXTERNAL_SENSOR_OK) {
-            // start getting values
-            dataUpdate();
-        } else {
-            // config error, no further actions triggered - Thing Status visible in UI
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "Configuration not valid. Sensor ID as a number is mandatory!");
-        }
-        lifecycleStatus = LifecycleStatus.RUNNING;
-    }
-
-    private void startSchedule() {
-        ScheduledFuture<?> localRefreshJob = refreshJob;
-        if (localRefreshJob != null) {
-            if (localRefreshJob.isCancelled()) {
-                refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 5, REFRESH_INTERVAL_MIN,
-                        TimeUnit.MINUTES);
-            } // else - scheduler is already running!
-        } else {
-            refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 5, REFRESH_INTERVAL_MIN, TimeUnit.MINUTES);
-        }
-    }
-
-    @Override
-    public void dispose() {
-        ScheduledFuture<?> localRefreshJob = refreshJob;
-        if (localRefreshJob != null) {
-            localRefreshJob.cancel(true);
-        }
-        lifecycleStatus = LifecycleStatus.DISPOSED;
-    }
-
-    /**
-     * Checks if config is valid - a) not null and b) sensorid is a number
-     *
-     * @param c
-     * @return
-     */
-    private ConfigStatus checkConfig(@Nullable LuftdatenInfoConfiguration c) {
-        if (c != null) {
-            if (c.ipAddress != null && !Constants.EMPTY.equals(c.ipAddress)) {
-                sensorUrl = Optional.of("http://" + c.ipAddress + "/data.json");
-                return ConfigStatus.INTERNAL_SENSOR_OK;
-            } else {
-                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;
-        }
-    }
-
-    public LifecycleStatus getLifecycleStatus() {
-        return lifecycleStatus;
-    }
-
-    protected void dataUpdate() {
-        if (sensorUrl.isPresent()) {
-            HTTPHandler.getHandler().request(sensorUrl.get(), this);
-        }
-    }
-
-    public void onResponse(String 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);
-    }
-
-    public void onError(String errorReason) {
-        statusUpdate(UpdateStatus.CONNECTION_EXCEPTION,
-                errorReason + " / " + LocalDateTime.now().format(DateTimeUtils.DTF));
-    }
-
-    protected void statusUpdate(UpdateStatus updateStatus, String details) {
-        if (updateStatus == UpdateStatus.OK) {
-            updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
-            startSchedule();
-        } else {
-            switch (updateStatus) {
-                case CONNECTION_ERROR:
-                    // start job even first update delivers no data - recovery is possible
-                    startSchedule();
-                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                            "Update failed due to Connection error. Trying to recover in next refresh");
-                    break;
-                case CONNECTION_EXCEPTION:
-                    // start job even first update delivers a Connection Exception - recovery is possible
-                    startSchedule();
-                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, details);
-                    break;
-                case VALUE_EMPTY:
-                    // start job even if first update delivers no values - recovery possible
-                    startSchedule();
-                    updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE,
-                            "No values delivered by Sensor. Trying to recover in next refresh");
-                    break;
-                case VALUE_ERROR:
-                    // final status - values from sensor are wrong and manual check is needed
-                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                            "Sensor values doesn't match - please check if Sensor ID is delivering the correct Thing channel values");
-                    break;
-                default:
-                    // final status - Configuration is wrong
-                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                            "Error during update - please check your config data");
-                    break;
-            }
-        }
-    }
-
-    @Override
-    protected void updateStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String description) {
-        myThingStatus = status;
-        super.updateStatus(status, statusDetail, description);
-    }
-
-    protected abstract UpdateStatus updateChannels(@Nullable String json);
-
-    protected abstract void updateFromCache();
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/ConditionHandler.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/ConditionHandler.java
deleted file mode 100644 (file)
index 2c9e376..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.handler;
-
-import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
-import static org.openhab.core.library.unit.MetricPrefix.HECTO;
-
-import java.util.List;
-
-import javax.measure.quantity.Dimensionless;
-import javax.measure.quantity.Pressure;
-import javax.measure.quantity.Temperature;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
-import org.openhab.binding.luftdateninfo.internal.utils.NumberUtils;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.SIUnits;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.Thing;
-
-/**
- * The {@link ConditionHandler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@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, HECTO(SIUnits.PASCAL));
-    protected QuantityType<Pressure> pressureSeaCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL));
-
-    public ConditionHandler(Thing thing) {
-        super(thing);
-    }
-
-    @Override
-    public UpdateStatus updateChannels(@Nullable String json) {
-        if (json != null) {
-            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
-            if (valueList != null) {
-                if (HTTPHandler.getHandler().isCondition(valueList)) {
-                    valueList.forEach(v -> {
-                        if (v.getValueType().endsWith(TEMPERATURE)) {
-                            temperatureCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
-                                    SIUnits.CELSIUS);
-                            updateState(TEMPERATURE_CHANNEL, temperatureCache);
-                        } else if (v.getValueType().endsWith(HUMIDITY)) {
-                            humidityCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.PERCENT);
-                            updateState(HUMIDITY_CHANNEL, humidityCache);
-                        } 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().endsWith(PRESSURE_SEALEVEL)) {
-                            pressureSeaCache = QuantityType.valueOf(
-                                    NumberUtils.round(NumberUtils.convert(v.getValue()) / 100, 1),
-                                    HECTO(SIUnits.PASCAL));
-                            updateState(PRESSURE_SEA_CHANNEL, pressureSeaCache);
-                        }
-                    });
-                    return UpdateStatus.OK;
-                } else {
-                    return UpdateStatus.VALUE_ERROR;
-                }
-            } else {
-                return UpdateStatus.VALUE_EMPTY;
-            }
-        } else {
-            return UpdateStatus.CONNECTION_ERROR;
-        }
-    }
-
-    @Override
-    protected void updateFromCache() {
-        updateState(TEMPERATURE_CHANNEL, temperatureCache);
-        updateState(HUMIDITY_CHANNEL, humidityCache);
-        updateState(PRESSURE_CHANNEL, pressureCache);
-        updateState(PRESSURE_SEA_CHANNEL, pressureSeaCache);
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/HTTPHandler.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/HTTPHandler.java
deleted file mode 100644 (file)
index 99c30dc..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.handler;
-
-import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.util.BufferingResponseListener;
-import org.openhab.binding.luftdateninfo.internal.dto.SensorData;
-import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
-import org.openhab.binding.luftdateninfo.internal.utils.DateTimeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.Gson;
-
-/**
- * The {@link HTTPHandler} is responsible for HTTP requests and JSON handling
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class HTTPHandler {
-    private final Logger logger = LoggerFactory.getLogger(HTTPHandler.class);
-
-    private static final Gson GSON = new Gson();
-    private static final HTTPHandler HTTP_HANDLER = new HTTPHandler();
-
-    private static @Nullable HttpClient commonHttpClient;
-
-    public static void init(HttpClient httpClient) {
-        commonHttpClient = httpClient;
-    }
-
-    public static HTTPHandler getHandler() {
-        return HTTP_HANDLER;
-    }
-
-    public synchronized void request(String url, BaseSensorHandler callback) {
-        HttpClient localClient = commonHttpClient;
-        if (localClient == null) {
-            logger.warn("HTTP Client not initialized");
-        } else {
-            Request req = localClient.newRequest(url);
-            req.timeout(15, TimeUnit.SECONDS).send(new BufferingResponseListener() {
-                @NonNullByDefault({})
-                @Override
-                public void onComplete(org.eclipse.jetty.client.api.Result result) {
-                    if (result.getResponse().getStatus() != 200) {
-                        String failure;
-                        if (result.getResponse().getReason() != null) {
-                            failure = result.getResponse().getReason();
-                        } else {
-                            failure = result.getFailure().getMessage();
-                        }
-                        callback.onError(Objects.requireNonNullElse(failure, "Unknown error"));
-                    } else {
-                        callback.onResponse(getContentAsString());
-                    }
-                }
-            });
-        }
-    }
-
-    public @Nullable List<SensorDataValue> getLatestValues(String response) {
-        SensorData[] valueArray = GSON.fromJson(response, SensorData[].class);
-        if (valueArray.length == 0) {
-            return null;
-        } else if (valueArray.length == 1) {
-            SensorData v = valueArray[0];
-            return v.getSensorDataValues();
-        } else if (valueArray.length > 1) {
-            // declare first item as latest
-            SensorData latestData = valueArray[0];
-            String latestTimeStr = latestData.getTimeStamp();
-            LocalDateTime latestTime = DateTimeUtils.toDate(latestTimeStr);
-            if (latestTime == null) {
-                logDateConversionError(response, latestData);
-            }
-            for (int i = 1; i < valueArray.length; i++) {
-                SensorData iterData = valueArray[i];
-                String iterTimeStr = iterData.getTimeStamp();
-                LocalDateTime iterTime = DateTimeUtils.toDate(iterTimeStr);
-                if (iterTime == null) {
-                    logDateConversionError(response, latestData);
-                }
-                if (iterTime != null && latestTime != null) {
-                    if (latestTime.isBefore(iterTime)) {
-                        // found item is newer - take it as latest
-                        latestTime = iterTime;
-                        latestData = iterData;
-                    } // else - found item is older - nothing to do
-
-                } else {
-                    logger.warn("One or two dates cannot be decoded 1) {} 2) {}", iterTimeStr, latestTimeStr);
-                }
-            }
-            return latestData.getSensorDataValues();
-        } else {
-            return null;
-        }
-    }
-
-    public void logDateConversionError(final String response, final Object dto) {
-        logger.warn("Unable to get timestamp");
-        logger.warn("Response: {}", response);
-        String json = GSON.toJson(dto);
-        logger.warn("GSon: {}", json);
-    }
-
-    public boolean isParticulate(@Nullable List<SensorDataValue> valueList) {
-        if (valueList == null) {
-            return false;
-        }
-        return valueList.stream().map(v -> v.getValueType()).filter(t -> t.endsWith(P1) || t.endsWith(P2)).findAny()
-                .isPresent();
-    }
-
-    public boolean isCondition(@Nullable List<SensorDataValue> valueList) {
-        if (valueList == null) {
-            return false;
-        }
-        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) {
-        if (valueList == null) {
-            return false;
-        }
-        return valueList.stream().map(v -> v.getValueType())
-                .filter(t -> t.endsWith(NOISE_EQ) || t.endsWith(NOISE_MAX) || t.endsWith(NOISE_MIN)).findAny()
-                .isPresent();
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/NoiseHandler.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/NoiseHandler.java
deleted file mode 100644 (file)
index 509631d..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.handler;
-
-import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
-
-import java.util.List;
-
-import javax.measure.quantity.Dimensionless;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
-import org.openhab.binding.luftdateninfo.internal.utils.NumberUtils;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.Thing;
-
-/**
- * The {@link NoiseHandler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class NoiseHandler extends BaseSensorHandler {
-    protected QuantityType<Dimensionless> noiseEQCache = QuantityType.valueOf(-1, Units.DECIBEL);
-    protected QuantityType<Dimensionless> noiseMinCache = QuantityType.valueOf(-1, Units.DECIBEL);
-    protected QuantityType<Dimensionless> noiseMaxCache = QuantityType.valueOf(-1, Units.DECIBEL);
-
-    public NoiseHandler(Thing thing) {
-        super(thing);
-    }
-
-    @Override
-    public UpdateStatus updateChannels(@Nullable String json) {
-        if (json != null) {
-            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
-            if (valueList != null) {
-                if (HTTPHandler.getHandler().isNoise(valueList)) {
-                    valueList.forEach(v -> {
-                        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().endsWith(NOISE_MIN)) {
-                            noiseMinCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
-                            updateState(NOISE_MIN_CHANNEL, noiseMinCache);
-                        } else if (v.getValueType().endsWith(NOISE_MAX)) {
-                            noiseMaxCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
-                            updateState(NOISE_MAX_CHANNEL, noiseMaxCache);
-                        }
-                    });
-                    return UpdateStatus.OK;
-                } else {
-                    return UpdateStatus.VALUE_ERROR;
-                }
-            } else {
-                return UpdateStatus.VALUE_EMPTY;
-            }
-        } else {
-            return UpdateStatus.CONNECTION_ERROR;
-        }
-    }
-
-    @Override
-    protected void updateFromCache() {
-        updateState(NOISE_EQ_CHANNEL, noiseEQCache);
-        updateState(NOISE_MIN_CHANNEL, noiseMinCache);
-        updateState(NOISE_MAX_CHANNEL, noiseMaxCache);
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/PMHandler.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/PMHandler.java
deleted file mode 100644 (file)
index 7ee0aa3..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.handler;
-
-import static org.openhab.binding.luftdateninfo.internal.LuftdatenInfoBindingConstants.*;
-import static org.openhab.binding.luftdateninfo.internal.utils.Constants.*;
-
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.dto.SensorDataValue;
-import org.openhab.binding.luftdateninfo.internal.utils.NumberUtils;
-import org.openhab.core.library.dimension.Density;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.Thing;
-
-/**
- * The {@link PMHandler} is responsible for handling commands, which are
- * sent to one of the channels.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class PMHandler extends BaseSensorHandler {
-
-    protected QuantityType<Density> pm25Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE);
-    protected QuantityType<Density> pm100Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE);
-
-    public PMHandler(Thing thing) {
-        super(thing);
-    }
-
-    @Override
-    public UpdateStatus updateChannels(@Nullable String json) {
-        if (json != null) {
-            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
-            if (valueList != null) {
-                if (HTTPHandler.getHandler().isParticulate(valueList)) {
-                    valueList.forEach(v -> {
-                        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().endsWith(P2)) {
-                            pm25Cache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
-                                    Units.MICROGRAM_PER_CUBICMETRE);
-                            updateState(PM25_CHANNEL, pm25Cache);
-                        }
-                    });
-                    return UpdateStatus.OK;
-                } else {
-                    return UpdateStatus.VALUE_ERROR;
-                }
-            } else {
-                return UpdateStatus.VALUE_EMPTY;
-            }
-        } else {
-            return UpdateStatus.CONNECTION_ERROR;
-        }
-    }
-
-    @Override
-    protected void updateFromCache() {
-        updateState(PM25_CHANNEL, pm25Cache);
-        updateState(PM100_CHANNEL, pm100Cache);
-    }
-}
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
deleted file mode 100644 (file)
index 71181ac..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/DateTimeUtils.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/DateTimeUtils.java
deleted file mode 100644 (file)
index f366941..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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 java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
-import java.util.Locale;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link DateTimeUtils} class provides helpers for converting Dates and Times.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class DateTimeUtils {
-    public static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
-    private static final Logger LOGGER = LoggerFactory.getLogger(DateTimeUtils.class);
-
-    public static synchronized @Nullable LocalDateTime toDate(String dateTime) {
-        try {
-            return LocalDateTime.from(DTF.parse(dateTime));
-
-        } catch (DateTimeParseException e) {
-            LOGGER.debug("Unable to parse date {}", dateTime);
-            return null;
-        }
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/NumberUtils.java b/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/NumberUtils.java
deleted file mode 100644 (file)
index 50a628d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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 NumberUtils} class provides helpers for converting Numbers.
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class NumberUtils {
-    public static final double UNDEF = Double.NaN;
-
-    public static double round(Object o, int places) {
-        double value = convert(o);
-
-        // for negative places return plain number
-        if (places < 0) {
-            return value;
-        }
-
-        long factor = (long) Math.pow(10, places);
-        value = value * factor;
-        long tmp = Math.round(value);
-        return (double) tmp / factor;
-    }
-
-    public static double convert(Object o) {
-        // ensure value not null
-        double value = UNDEF;
-        if (o instanceof Number) {
-            value = ((Number) o).doubleValue();
-        } else if (o instanceof String) {
-            value = Double.parseDouble(o.toString());
-        }
-        return value;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/addon/addon.xml b/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/addon/addon.xml
deleted file mode 100644 (file)
index 3718495..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<addon:addon id="luftdateninfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
-       xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
-
-       <type>binding</type>
-       <name>LuftdatenInfo Binding</name>
-       <description>Binding to integrate DIY Sensors from luftdaten.info Sensor Community</description>
-       <connection>hybrid</connection>
-
-</addon:addon>
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo.properties b/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo.properties
deleted file mode 100644 (file)
index de36138..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# add-on
-
-addon.luftdateninfo.name = LuftdatenInfo Binding
-addon.luftdateninfo.description = Binding to integrate DIY Sensors from luftdaten.info Sensor Community
-
-# thing types
-
-thing-type.luftdateninfo.conditions.label = Condition Sensor
-thing-type.luftdateninfo.conditions.description = Sensor to measure Temperature and Humidity conditions
-thing-type.luftdateninfo.noise.label = Noise Sensor
-thing-type.luftdateninfo.noise.description = Sensor to measure noise on location
-thing-type.luftdateninfo.particulate.label = Particulate Sensor
-thing-type.luftdateninfo.particulate.description = Sensor to measure Particulate Matter (PM)
-
-# thing types config
-
-thing-type.config.luftdateninfo.conditions.ipAddress.label = Internal IP Address
-thing-type.config.luftdateninfo.conditions.ipAddress.description = Local IP address of your personal owned sensor
-thing-type.config.luftdateninfo.conditions.sensorid.label = External Sensor ID
-thing-type.config.luftdateninfo.conditions.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
-thing-type.config.luftdateninfo.noise.ipAddress.label = Internal IP Address
-thing-type.config.luftdateninfo.noise.ipAddress.description = Local IP address of your personal owned sensor
-thing-type.config.luftdateninfo.noise.sensorid.label = External Sensor ID
-thing-type.config.luftdateninfo.noise.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
-thing-type.config.luftdateninfo.particulate.ipAddress.label = Internal IP Address
-thing-type.config.luftdateninfo.particulate.ipAddress.description = Local IP address of your personal owned sensor
-thing-type.config.luftdateninfo.particulate.sensorid.label = External Sensor ID
-thing-type.config.luftdateninfo.particulate.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
-
-# channel types
-
-channel-type.luftdateninfo.hum-channel.label = Humidity
-channel-type.luftdateninfo.hum-channel.description = Humidity from the selected Sensor ID
-channel-type.luftdateninfo.noise-eq-channel.label = Average Noise
-channel-type.luftdateninfo.noise-eq-channel.description = Average noise level from the selected Sensor ID
-channel-type.luftdateninfo.noise-max-channel.label = Maximum Noise
-channel-type.luftdateninfo.noise-max-channel.description = Maximum noise level (last 2.5 minutes) from the selected Sensor ID
-channel-type.luftdateninfo.noise-min-channel.label = Minimum Noise
-channel-type.luftdateninfo.noise-min-channel.description = Minimum noise level (last 2.5 minutes) from the selected Sensor ID
-channel-type.luftdateninfo.pm100-channel.label = Particulate Matter category 10.0
-channel-type.luftdateninfo.pm25-channel.label = Particulate Matter category 2.5
-channel-type.luftdateninfo.pressure-channel.label = Atmospheric Pressure
-channel-type.luftdateninfo.pressure-channel.description = Atmospheric Pressure from the selected Sensor ID
-channel-type.luftdateninfo.pressure-sea-channel.label = Atmospheric Pressure Sea Level
-channel-type.luftdateninfo.pressure-sea-channel.description = Atmospheric Pressure at sea level from the selected Sensor ID
-channel-type.luftdateninfo.temp-channel.label = Temperature
-channel-type.luftdateninfo.temp-channel.description = Temperature from the selected Sensor ID
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo_de.properties b/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo_de.properties
deleted file mode 100644 (file)
index 1ba9feb..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# add-on
-
-addon.luftdateninfo.name = LuftdatenInfo Binding
-addon.luftdateninfo.description = Das Binding stellt die Daten der Eigenbau-Sensoren von LuftdatenInfo zur Verfügung
-
-# thing types
-
-thing-type.luftdateninfo.conditions.label = Umweltsensor
-thing-type.luftdateninfo.conditions.description = Messung der Temperatur, Luftfeuchtigkeit und Luftdruck 
-thing-type.luftdateninfo.noise.label = Lärmsensor
-thing-type.luftdateninfo.noise.description = Messung der Lärmbelastung in der Umgebung 
-thing-type.luftdateninfo.particulate.label = Feinstaubsensor
-thing-type.luftdateninfo.particulate.description = Messung der Feinstaubbelastung in der Umgebung 
-
-# thing types config
-
-thing-type.config.luftdateninfo.conditions.ipAddress.label = Interne IP-Adresse
-thing-type.config.luftdateninfo.conditions.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
-thing-type.config.luftdateninfo.conditions.sensorid.label = Externe Sensor-ID
-thing-type.config.luftdateninfo.conditions.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
-thing-type.config.luftdateninfo.noise.ipAddress.label = Interne IP-Adresse
-thing-type.config.luftdateninfo.noise.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
-thing-type.config.luftdateninfo.noise.sensorid.label = Externe Sensor-ID
-thing-type.config.luftdateninfo.noise.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
-thing-type.config.luftdateninfo.particulate.ipAddress.label = Interne IP-Adresse
-thing-type.config.luftdateninfo.particulate.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
-thing-type.config.luftdateninfo.particulate.sensorid.label = Externe Sensor-ID
-thing-type.config.luftdateninfo.particulate.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
-
-# channel types
-
-channel-type.luftdateninfo.hum-channel.label = Luftfeuchtigkeit
-channel-type.luftdateninfo.hum-channel.description = Luftfeuchtigkeit der ausgewählten Sensor-ID
-channel-type.luftdateninfo.noise-eq-channel.label = Durchschnittlicher Lärmpegel
-channel-type.luftdateninfo.noise-eq-channel.description = Durchschnittlicher Rauschpegel der ausgewählten Sensor-ID
-channel-type.luftdateninfo.noise-max-channel.label = Maximaler Lärmpegel 
-channel-type.luftdateninfo.noise-max-channel.description = Maximaler Rauschpegel (letzte 2,5 Minuten) der ausgewählten Sensor-ID
-channel-type.luftdateninfo.noise-min-channel.label = Minimaler Lärmpegel 
-channel-type.luftdateninfo.noise-min-channel.description = Minimaler Rauschpegel (letzte 2,5 Minuten) der ausgewählten Sensor-ID
-channel-type.luftdateninfo.pm100-channel.label = Feinstaub der Kategorie PM 10.0
-channel-type.luftdateninfo.pm25-channel.label = Feinstaub der Kategorie PM 2.5
-channel-type.luftdateninfo.pressure-channel.label = Atmosphärischer Druck
-channel-type.luftdateninfo.pressure-channel.description = Atmosphärischer Druck der ausgewählten Sensor-ID
-channel-type.luftdateninfo.pressure-sea-channel.label = Atmosphärischer Druck Auf Meereshöhe
-channel-type.luftdateninfo.pressure-sea-channel.description = Atmosphärischer Druck auf Seehöhe der ausgewählten Sensor-ID
-channel-type.luftdateninfo.temp-channel.label = Temperatur
-channel-type.luftdateninfo.temp-channel.description = Temperatur der ausgewählten Sensor-ID
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/thing/thing-types.xml
deleted file mode 100644 (file)
index 001a2c1..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<thing:thing-descriptions bindingId="luftdateninfo"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
-       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
-
-       <thing-type id="particulate">
-               <label>Particulate Sensor</label>
-               <description>Sensor to measure Particulate Matter (PM)</description>
-
-               <channels>
-                       <channel id="pm25" typeId="pm25-channel"/>
-                       <channel id="pm100" typeId="pm100-channel"/>
-               </channels>
-
-               <config-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>
-
-       <thing-type id="conditions">
-               <label>Condition Sensor</label>
-               <description>Sensor to measure Temperature and Humidity conditions</description>
-
-               <channels>
-                       <channel id="temperature" typeId="temp-channel"/>
-                       <channel id="humidity" typeId="hum-channel"/>
-                       <channel id="pressure" typeId="pressure-channel"/>
-                       <channel id="pressure-sea" typeId="pressure-sea-channel"/>
-               </channels>
-
-               <config-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>
-
-       <thing-type id="noise">
-               <label>Noise Sensor</label>
-               <description>Sensor to measure noise on location</description>
-
-               <channels>
-                       <channel id="noise-eq" typeId="noise-eq-channel"/>
-                       <channel id="noise-min" typeId="noise-min-channel"/>
-                       <channel id="noise-max" typeId="noise-max-channel"/>
-               </channels>
-
-               <config-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>
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/ConditionHandlerTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/ConditionHandlerTest.java
deleted file mode 100644 (file)
index eb9f52f..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.openhab.core.library.unit.MetricPrefix.HECTO;
-
-import java.util.HashMap;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.luftdateninfo.internal.handler.BaseSensorHandler.UpdateStatus;
-import org.openhab.binding.luftdateninfo.internal.mock.ConditionHandlerExtension;
-import org.openhab.binding.luftdateninfo.internal.mock.ThingMock;
-import org.openhab.binding.luftdateninfo.internal.util.FileReader;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.SIUnits;
-import org.openhab.core.library.unit.Units;
-
-/**
- * The {@link ConditionHandlerTest} Test Condition Handler updates
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class ConditionHandlerTest {
-
-    @Test
-    public void testValidNoPressureUpdate() {
-        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);
-
-        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
-        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        if (pmJson != null) {
-            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., 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);
-        }
-    }
-
-    @Test
-    public void testValidWithPressureUpdate() {
-        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);
-
-        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
-        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-plus-pressure.json");
-        if (pmJson != null) {
-            UpdateStatus result = condHandler.updateChannels(pmJson);
-            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(1002.0, HECTO(SIUnits.PASCAL)), condHandler.getPressure(), "Pressure");
-            assertEquals(QuantityType.valueOf(1019.7, HECTO(SIUnits.PASCAL)), condHandler.getPressureSea(),
-                    "Pressure Sea");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testInvalidUpdate() {
-        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);
-
-        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
-        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
-        if (pmJson != null) {
-            UpdateStatus result = condHandler.updateChannels(pmJson);
-            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testEmptyUpdate() {
-        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);
-
-        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
-        UpdateStatus result = condHandler.updateChannels("[]");
-        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
-    }
-
-    @Test
-    public void testNullUpdate() {
-        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);
-
-        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
-        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);
-        }
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/DTOTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/DTOTest.java
deleted file mode 100644 (file)
index 2e203d6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.List;
-
-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.util.FileReader;
-import org.openhab.binding.luftdateninfo.internal.utils.Constants;
-
-import com.google.gson.Gson;
-
-/**
- * The {@link DTOTest} Data Transfer Object - test conversions
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class DTOTest {
-
-    @Test
-    public void testConditions() {
-        String result = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        Gson gson = new Gson();
-        SensorData[] valueArray = gson.fromJson(result, SensorData[].class);
-        // System.out.println(valueArray.length);
-        assertEquals(2, valueArray.length, "Array size");
-
-        SensorData d = valueArray[0];
-        // Assure latest data is taken
-        String dateStr = d.getTimeStamp();
-        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 (Constants.TEMPERATURE.equals(v.getValueType())) {
-                assertEquals("22.70", v.getValue(), "Temperature");
-            } else if (Constants.HUMIDITY.equals(v.getValueType())) {
-                assertEquals("61.00", v.getValue(), "Humidity");
-            }
-        });
-    }
-
-    @Test
-    public void testDecoding() {
-        String result = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        Gson gson = new Gson();
-        SensorData[] valueArray = gson.fromJson(result, SensorData[].class);
-        // System.out.println(valueArray.length);
-        assertEquals(2, valueArray.length, "Array size");
-
-        SensorData d = valueArray[0];
-        // Assure latest data is taken
-        String dateStr = d.getTimeStamp();
-        if (dateStr.equals("2020-06-09 06:38:08")) {
-            // take newer one
-            d = valueArray[1];
-        }
-
-        // test decoding a small part
-        String json = gson.toJson(d);
-        // System.out.println(json);
-        // check if correct timestamp is included
-        assertTrue(json.contains("\"timestamp\":\"2020-06-09 06:40:34\""));
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerEvalTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerEvalTest.java
deleted file mode 100644 (file)
index f04248b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.List;
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.junit.jupiter.api.BeforeEach;
-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;
-
-/**
- * The {@link HTTPHandlerEvalTest} test all evaluations on SensorDataValues
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class HTTPHandlerEvalTest {
-
-    private @Nullable List<SensorDataValue> conditions;
-    private @Nullable List<SensorDataValue> particulate;
-    private @Nullable List<SensorDataValue> noise;
-    private HTTPHandler http = new HTTPHandler();
-
-    @BeforeEach
-    public void setUp() {
-        String conditionsStr = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        assertNotNull(conditionsStr);
-        Objects.requireNonNull(conditionsStr);
-        conditions = http.getLatestValues(conditionsStr);
-
-        String particulateStr = FileReader.readFileInString("src/test/resources/pm-result.json");
-        assertNotNull(particulateStr);
-        Objects.requireNonNull(particulateStr);
-        particulate = http.getLatestValues(particulateStr);
-
-        String noiseStr = FileReader.readFileInString("src/test/resources/noise-result.json");
-        assertNotNull(noiseStr);
-        Objects.requireNonNull(noiseStr);
-        noise = http.getLatestValues(noiseStr);
-    }
-
-    @Test
-    public void testIsCondition() {
-        assertTrue(http.isCondition(conditions));
-        assertFalse(http.isCondition(particulate));
-        assertFalse(http.isCondition(noise));
-        assertFalse(http.isCondition(null));
-    }
-
-    @Test
-    public void testIsParticulate() {
-        assertFalse(http.isParticulate(conditions));
-        assertTrue(http.isParticulate(particulate));
-        assertFalse(http.isParticulate(noise));
-        assertFalse(http.isParticulate(null));
-    }
-
-    @Test
-    public void testIsNoise() {
-        assertFalse(http.isNoise(conditions));
-        assertFalse(http.isNoise(particulate));
-        assertTrue(http.isNoise(noise));
-        assertFalse(http.isNoise(null));
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerValueTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerValueTest.java
deleted file mode 100644 (file)
index 8d3a7ba..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.List;
-import java.util.Objects;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-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
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class HTTPHandlerValueTest {
-    private HTTPHandler http = new HTTPHandler();
-
-    /**
-     * test if really the latest values are returned
-     * resource1 is json with ordering according to time while resource2 the entries flipped
-     */
-    @Test
-    public void testValueDecoding() {
-        String resource1 = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        assertNotNull(resource1);
-        Objects.requireNonNull(resource1);
-        List<SensorDataValue> l = http.getLatestValues(resource1);
-        assertNotNull(l);
-        Objects.requireNonNull(l);
-        l.forEach(sd -> {
-            testSensorValue(sd);
-        });
-
-        String resource2 = FileReader
-                .readFileInString("src/test/resources/condition-result-no-pressure-flipped-values.json");
-        assertNotNull(resource2);
-        Objects.requireNonNull(resource2);
-        l = http.getLatestValues(resource2);
-        assertNotNull(l);
-        Objects.requireNonNull(l);
-        l.forEach(sd -> {
-            testSensorValue(sd);
-        });
-    }
-
-    private void testSensorValue(SensorDataValue s) {
-        if (s.getValueType().equals(Constants.TEMPERATURE)) {
-            assertEquals("22.70", s.getValue(), "Temperature resource 1");
-        } else if (s.getValueType().equals(Constants.HUMIDITY)) {
-            assertEquals("61.00", s.getValue(), "Humidity resource 1");
-        } else {
-            assertTrue(false);
-        }
-        // System.out.println(s.getValue_type() + ":" + s.getValue());
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NoiseHandlerTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NoiseHandlerTest.java
deleted file mode 100644 (file)
index 22428b1..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.HashMap;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.luftdateninfo.internal.handler.BaseSensorHandler.UpdateStatus;
-import org.openhab.binding.luftdateninfo.internal.mock.NoiseHandlerExtension;
-import org.openhab.binding.luftdateninfo.internal.mock.ThingMock;
-import org.openhab.binding.luftdateninfo.internal.util.FileReader;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-
-/**
- * The {@link NoiseHandlerTest} Test Noise Handler updates
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class NoiseHandlerTest {
-
-    @Test
-    public void testValidUpdate() {
-        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);
-
-        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
-        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
-        if (pmJson != null) {
-            UpdateStatus result = noiseHandler.updateChannels(pmJson);
-            assertEquals(UpdateStatus.OK, result, "Valid update");
-            assertEquals(QuantityType.valueOf(51.0, Units.DECIBEL), noiseHandler.getNoiseEQCache(), "Noise EQ");
-            assertEquals(QuantityType.valueOf(47.2, Units.DECIBEL), noiseHandler.getNoiseMinCache(), "Noise Min");
-            assertEquals(QuantityType.valueOf(57.0, Units.DECIBEL), noiseHandler.getNoiseMaxCache(), "Noise Max");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testInvalidUpdate() {
-        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);
-
-        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
-        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
-        if (pmJson != null) {
-            UpdateStatus result = noiseHandler.updateChannels(pmJson);
-            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
-            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseEQCache(), "Values undefined");
-            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseMinCache(), "Values undefined");
-            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseMaxCache(), "Values undefined");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testEmptyUpdate() {
-        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);
-
-        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
-        UpdateStatus result = noiseHandler.updateChannels("[]");
-        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
-    }
-
-    @Test
-    public void testNullUpdate() {
-        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);
-
-        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
-        UpdateStatus result = noiseHandler.updateChannels(null);
-        assertEquals(UpdateStatus.CONNECTION_ERROR, result, "Valid update");
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NumberTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NumberTest.java
deleted file mode 100644 (file)
index e2206e9..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.luftdateninfo.internal.utils.NumberUtils;
-
-/**
- * The {@link NumberTest} Test rounding and converting Numbers
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class NumberTest {
-
-    @Test
-    public void testRoundingUp() {
-        double d1 = 1.95;
-        double d1r2 = NumberUtils.round(d1, 2);
-        assertEquals("1.95", Double.toString(d1r2), "Double 1.95, 2 places");
-        // System.out.println("D1R2 " + d1r2);
-        double d1r1 = NumberUtils.round(d1, 1);
-        // System.out.println("D1R1 " + d1r1);
-        assertEquals("2.0", Double.toString(d1r1), "Double 1.95, 1 place");
-    }
-
-    @Test
-    public void testRoundingDown() {
-        double d1 = 1.94;
-        double d1r2 = NumberUtils.round(d1, 2);
-        assertEquals("1.94", Double.toString(d1r2), "Double 1.94, 2 places");
-        // System.out.println("D1R2 " + d1r2);
-        double d1r1 = NumberUtils.round(d1, 1);
-        // System.out.println("D1R1 " + d1r1);
-        assertEquals("1.9", Double.toString(d1r1), "Double 1.94, 1 place");
-    }
-
-    @Test
-    public void testStringNumbers() {
-        String d1 = "1.94";
-        double d1r2 = NumberUtils.round(d1, 2);
-        assertEquals("1.94", Double.toString(d1r2), "Double 1.94, 2 places");
-        // System.out.println("D1R2 " + d1r2);
-        double d1r1 = NumberUtils.round(d1, 1);
-        // System.out.println("D1R1 " + d1r1);
-        assertEquals("1.9", Double.toString(d1r1), "Double 1.94, 1 place");
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/PMHandlerTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/PMHandlerTest.java
deleted file mode 100644 (file)
index ae8026a..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.HashMap;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.luftdateninfo.internal.handler.BaseSensorHandler.ConfigStatus;
-import org.openhab.binding.luftdateninfo.internal.handler.BaseSensorHandler.LifecycleStatus;
-import org.openhab.binding.luftdateninfo.internal.handler.BaseSensorHandler.UpdateStatus;
-import org.openhab.binding.luftdateninfo.internal.mock.PMHandlerExtension;
-import org.openhab.binding.luftdateninfo.internal.mock.ThingMock;
-import org.openhab.binding.luftdateninfo.internal.util.FileReader;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.unit.Units;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link PMHandlerTest} Test Particualte Matter Handler - Config and updates
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class PMHandlerTest {
-    private Logger logger = LoggerFactory.getLogger(PMHandlerTest.class);
-
-    @Test
-    public void testValidConfigStatus() {
-        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();
-        logger.info("LC status: {}", pmHandler.getLifecycleStatus());
-        int retryCount = 0; // Test shall fail after max 10 seconds
-        while (pmHandler.getLifecycleStatus() != LifecycleStatus.RUNNING && retryCount < 20) {
-            try {
-                logger.info("LC running not reached - wait");
-                Thread.sleep(500);
-                retryCount++;
-            } catch (InterruptedException e) {
-                // nothing to do
-            }
-        }
-        /*
-         * 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.EXTERNAL_SENSOR_OK, pmHandler.getConfigStatus(), "Handler Configuration status");
-    }
-
-    @Test
-    public void testInvalidConfigStatus() {
-        ThingMock t = new ThingMock();
-
-        HashMap<String, Object> properties = new HashMap<String, Object>();
-        // String sensorid taken from thing-types.xml
-        properties.put("sensorid", -1);
-        t.setConfiguration(properties);
-
-        PMHandlerExtension pmHandler = new PMHandlerExtension(t);
-        pmHandler.initialize();
-        logger.info("LC status: {}", pmHandler.getLifecycleStatus());
-        int retryCount = 0; // Test shall fail after max 10 seconds
-        while (pmHandler.getLifecycleStatus() != LifecycleStatus.RUNNING && retryCount < 20) {
-            try {
-                logger.info("LC running not reached - wait");
-                Thread.sleep(500);
-                retryCount++;
-            } catch (InterruptedException e) {
-                // nothing to do
-            }
-        }
-        /*
-         * Test if config status is 3 = CONFIG_SENSOR_NUMBER for invalid configuration with non-number sensorid. Take
-         * real int for comparison instead of BaseHandler constants - in case of change test needs to be adapted
-         */
-        assertEquals(ConfigStatus.SENSOR_ID_NEGATIVE, pmHandler.getConfigStatus(), "Handler Configuration status");
-    }
-
-    @Test
-    public void testValidUpdate() {
-        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/pm-result.json");
-        if (pmJson != null) {
-            UpdateStatus result = pmHandler.updateChannels(pmJson);
-            assertEquals(UpdateStatus.OK, result, "Valid update");
-            assertEquals(QuantityType.valueOf(2.9, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM25Cache(), "PM25");
-            assertEquals(QuantityType.valueOf(5.2, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM100Cache(), "PM100");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testInvalidUpdate() {
-        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);
-        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
-        if (pmJson != null) {
-            UpdateStatus result = pmHandler.updateChannels(pmJson);
-            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
-            assertEquals(QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM25Cache(),
-                    "Values undefined");
-            assertEquals(QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM100Cache(),
-                    "Values undefined");
-        } else {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testEmptyUpdate() {
-        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);
-        UpdateStatus result = pmHandler.updateChannels("[]");
-        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
-    }
-
-    @Test
-    public void testNullUpdate() {
-        ThingMock t = new ThingMock();
-
-        HashMap<String, Object> properties = new HashMap<String, Object>();
-        // String sensorid taken from thing-types.xml
-        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/java/org/openhab/binding/luftdateninfo/internal/mock/ConditionHandlerExtension.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ConditionHandlerExtension.java
deleted file mode 100644 (file)
index e7431f0..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.mock;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.handler.ConditionHandler;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.types.State;
-
-/**
- * The {@link NoiseHandlerExtension} Test Noise Handler Extension with additonal state queries
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class ConditionHandlerExtension extends ConditionHandler {
-
-    public ConditionHandlerExtension(Thing thing) {
-        super(thing);
-    }
-
-    public ConfigStatus getConfigStatus() {
-        return configStatus;
-    }
-
-    public UpdateStatus getUpdateStatus() {
-        return lastUpdateStatus;
-    }
-
-    public @Nullable State getTemperature() {
-        return temperatureCache;
-    }
-
-    public @Nullable State getHumidity() {
-        return humidityCache;
-    }
-
-    public @Nullable State getPressure() {
-        return pressureCache;
-    }
-
-    public @Nullable State getPressureSea() {
-        return pressureSeaCache;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/NoiseHandlerExtension.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/NoiseHandlerExtension.java
deleted file mode 100644 (file)
index 99f306d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.mock;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.handler.NoiseHandler;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.types.State;
-
-/**
- * The {@link NoiseHandlerExtension} Test Noise Handler Extension with additonal state queries
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class NoiseHandlerExtension extends NoiseHandler {
-
-    public NoiseHandlerExtension(Thing thing) {
-        super(thing);
-    }
-
-    public ConfigStatus getConfigStatus() {
-        return configStatus;
-    }
-
-    public UpdateStatus getUpdateStatus() {
-        return lastUpdateStatus;
-    }
-
-    public @Nullable State getNoiseEQCache() {
-        return noiseEQCache;
-    }
-
-    public @Nullable State getNoiseMinCache() {
-        return noiseMinCache;
-    }
-
-    public @Nullable State getNoiseMaxCache() {
-        return noiseMaxCache;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/PMHandlerExtension.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/PMHandlerExtension.java
deleted file mode 100644 (file)
index b04fd90..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.mock;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.luftdateninfo.internal.handler.PMHandler;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.types.State;
-
-/**
- * The {@link PMHandlerExtension} Test Particualte Matter Handler Extension with additonal state queries
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class PMHandlerExtension extends PMHandler {
-
-    public PMHandlerExtension(Thing thing) {
-        super(thing);
-    }
-
-    public ConfigStatus getConfigStatus() {
-        return configStatus;
-    }
-
-    public UpdateStatus getUpdateStatus() {
-        return lastUpdateStatus;
-    }
-
-    public @Nullable State getPM25Cache() {
-        return pm25Cache;
-    }
-
-    public @Nullable State getPM100Cache() {
-        return pm100Cache;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ThingMock.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ThingMock.java
deleted file mode 100644 (file)
index 060ef22..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.mock;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.config.core.Configuration;
-import org.openhab.core.thing.Channel;
-import org.openhab.core.thing.ChannelUID;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
-import org.openhab.core.thing.ThingStatusInfo;
-import org.openhab.core.thing.ThingTypeUID;
-import org.openhab.core.thing.ThingUID;
-import org.openhab.core.thing.binding.ThingHandler;
-
-/**
- * The {@link ThingMock} Thing Mock
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class ThingMock implements Thing {
-    private Configuration config = new Configuration();
-
-    @Override
-    public @Nullable String getLabel() {
-        return null;
-    }
-
-    @Override
-    public void setLabel(@Nullable String label) {
-    }
-
-    @Override
-    public List<Channel> getChannels() {
-        return new ArrayList<Channel>();
-    }
-
-    @Override
-    public List<Channel> getChannelsOfGroup(String channelGroupId) {
-        return new ArrayList<Channel>();
-    }
-
-    @Override
-    public @Nullable Channel getChannel(String channelId) {
-        return null;
-    }
-
-    @Override
-    public @Nullable Channel getChannel(ChannelUID channelUID) {
-        return null;
-    }
-
-    @Override
-    public ThingStatus getStatus() {
-        return ThingStatus.UNKNOWN;
-    }
-
-    @Override
-    public ThingStatusInfo getStatusInfo() {
-        return new ThingStatusInfo(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "");
-    }
-
-    @Override
-    public void setStatusInfo(ThingStatusInfo status) {
-    }
-
-    @Override
-    public void setHandler(@Nullable ThingHandler thingHandler) {
-    }
-
-    @Override
-    public @Nullable ThingHandler getHandler() {
-        return null;
-    }
-
-    @Override
-    public @Nullable ThingUID getBridgeUID() {
-        return null;
-    }
-
-    @Override
-    public void setBridgeUID(@Nullable ThingUID bridgeUID) {
-    }
-
-    @Override
-    public Configuration getConfiguration() {
-        return config;
-    }
-
-    public void setConfiguration(Map<String, Object> m) {
-        config = new Configuration(m);
-    }
-
-    @Override
-    public ThingUID getUID() {
-        return new ThingUID("luftdateninfo", "test");
-    }
-
-    @Override
-    public ThingTypeUID getThingTypeUID() {
-        return new ThingTypeUID("luftdateninfo:any");
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
-        return new HashMap<String, String>();
-    }
-
-    @Override
-    public @Nullable String setProperty(String name, @Nullable String value) {
-        return null;
-    }
-
-    @Override
-    public void setProperties(Map<String, String> properties) {
-    }
-
-    @Override
-    public @Nullable String getLocation() {
-        return null;
-    }
-
-    @Override
-    public void setLocation(@Nullable String location) {
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return false;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/DateTimeTest.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/DateTimeTest.java
deleted file mode 100644 (file)
index 13d2548..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.util;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeParseException;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.junit.jupiter.api.Test;
-import org.openhab.binding.luftdateninfo.internal.utils.DateTimeUtils;
-
-/**
- * The {@link DateTimeTest} Test DateTimeFormatter provided in utils package
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class DateTimeTest {
-
-    @Test
-    public void testJSonTime() {
-        String jsonDateString = "2020-08-14 14:53:21";
-        try {
-            LocalDateTime dt = LocalDateTime.from(DateTimeUtils.DTF.parse(jsonDateString));
-            assertEquals(14, dt.getDayOfMonth(), "Day");
-            assertEquals(8, dt.getMonthValue(), "Month");
-            assertEquals(2020, dt.getYear(), "Year");
-
-            String s = dt.format(DateTimeUtils.DTF);
-            assertEquals(jsonDateString, s, "String");
-        } catch (DateTimeParseException e) {
-            assertFalse(true);
-        }
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/FileReader.java b/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/FileReader.java
deleted file mode 100644 (file)
index 7898a4b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.util;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link FileReader} Helper Util to read test resource files
- *
- * @author Bernd Weymann - Initial contribution
- */
-@NonNullByDefault
-public class FileReader {
-
-    public static @Nullable String readFileInString(String filename) {
-        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "CP1252"));) {
-            StringBuffer buf = new StringBuffer();
-            String sCurrentLine;
-
-            while ((sCurrentLine = br.readLine()) != null) {
-                buf.append(sCurrentLine);
-            }
-            return buf.toString();
-        } catch (IOException e) {
-            // fail if file cannot be read
-            assertTrue(false);
-        }
-        return null;
-    }
-}
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure-flipped-values.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure-flipped-values.json
deleted file mode 100644 (file)
index 882456f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-[
-       {
-               "id": 731117559,
-               "sensordatavalues": [
-                       {
-                               "id": 1573660194,
-                               "value_type": "temperature",
-                               "value": "22.70"
-                       },
-                       {
-                               "id": 1573660195,
-                               "value_type": "humidity",
-                               "value": "61.00"
-                       }
-               ],
-               "timestamp": "2020-06-09 06:40:34",
-               "sampling_rate": null,
-               "location": {
-                       "id": 11447,
-                       "country": "DE",
-                       "altitude": "151.5",
-                       "latitude": "50.562",
-                       "longitude": "8.504",
-                       "indoor": 0,
-                       "exact_location": 0
-               },
-               "sensor": {
-                       "id": 22562,
-                       "pin": "7",
-                       "sensor_type": {
-                               "id": 9,
-                               "manufacturer": "various",
-                               "name": "DHT22"
-                       }
-               }
-       },
-       {
-               "id": 731094694,
-               "sensordatavalues": [
-                       {
-                               "id": 1573610869,
-                               "value_type": "temperature",
-                               "value": "22.50"
-                       },
-                       {
-                               "id": 1573610870,
-                               "value_type": "humidity",
-                               "value": "62.00"
-                       }
-               ],
-               "timestamp": "2020-06-09 06:38:08",
-               "sampling_ra
-               te": null,
-               "location": {
-                       "id": 11447,
-                       "country": "DE",
-                       "altitude": "151.5",
-                       "latitude": "50.562",
-                       "longitude": "8.504",
-                       "indoor": 0,
-                       "exact_location": 0
-               },
-               "sensor": {
-                       "id": 22562,
-                       "pin": "7",
-                       "sensor_type": {
-                               "id": 9,
-                               "manufacturer": "various",
-                               "name": "DHT22"
-                       }
-               }
-       }
-]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure.json
deleted file mode 100644 (file)
index 7c400eb..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-[
-       {
-               "id": 731094694,
-               "sensordatavalues": [
-                       {
-                               "id": 1573610869,
-                               "value_type": "temperature",
-                               "value": "22.50"
-                       },
-                       {
-                               "id": 1573610870,
-                               "value_type": "humidity",
-                               "value": "62.00"
-                       }
-               ],
-               "timestamp": "2020-06-09 06:38:08",
-               "sampling_rate": null,
-               "location": {
-                       "id": 11447,
-                       "country": "DE",
-                       "altitude": "151.5",
-                       "latitude": "50.562",
-                       "longitude": "8.504",
-                       "indoor": 0,
-                       "exact_location": 0
-               },
-               "sensor": {
-                       "id": 22562,
-                       "pin": "7",
-                       "sensor_type": {
-                               "id": 9,
-                               "manufacturer": "various",
-                               "name": "DHT22"
-                       }
-               }
-       },
-       {
-               "id": 731117559,
-               "sensordatavalues": [
-                       {
-                               "id": 1573660194,
-                               "value_type": "temperature",
-                               "value": "22.70"
-                       },
-                       {
-                               "id": 1573660195,
-                               "value_type": "humidity",
-                               "value": "61.00"
-                       }
-               ],
-               "timestamp": "2020-06-09 06:40:34",
-               "sampling_rate": null,
-               "location": {
-                       "id": 11447,
-                       "country": "DE",
-                       "altitude": "151.5",
-                       "latitude": "50.562",
-                       "longitude": "8.504",
-                       "indoor": 0,
-                       "exact_location": 0
-               },
-               "sensor": {
-                       "id": 22562,
-                       "pin": "7",
-                       "sensor_type": {
-                               "id": 9,
-                               "manufacturer": "various",
-                               "name": "DHT22"
-                       }
-               }
-       }
-]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-plus-pressure.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-plus-pressure.json
deleted file mode 100644 (file)
index 4d7a30b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-[
-       {
-               "id": 1038856661,
-               "sensor": {
-                       "id": 28843,
-                       "sensor_type": {
-                               "id": 17,
-                               "manufacturer": "Bosch",
-                               "name": "BME280"
-                       },
-                       "pin": "11"
-               },
-               "timestamp": "2020-07-03 09:39:46",
-               "sampling_rate": null,
-               "location": {
-                       "id": 15975,
-                       "altitude": "151.2",
-                       "longitude": "8.49543571448",
-                       "exact_location": 1,
-                       "latitude": "50.55591005174",
-                       "indoor": 0,
-                       "country": "DE"
-               },
-               "sensordatavalues": [
-                       {
-                               "id": 2237770681,
-                               "value_type": "temperature",
-                               "value": "21.52"
-                       },
-                       {
-                               "id": 2237770683,
-                               "value_type": "pressure",
-                               "value": "100199.97"
-                       },
-                       {
-                               "id": 2237770684,
-                               "value_type": "humidity",
-                               "value": "58.51"
-                       },
-                       {
-                               "value_type": "pressure_at_sealevel",
-                               "value": 101968.66
-                       }
-               ]
-       },
-       {
-               "id": 1038834126,
-               "sensor": {
-                       "id": 28843,
-                       "sensor_type": {
-                               "id": 17,
-                               "manufacturer": "Bosch",
-                               "name": "BME280"
-                       },
-                       "pin": "11"
-               },
-               "timestamp": "2020-07-03 09:37:21",
-               "sampling_rate": null,
-               "location": {
-                       "id": 15975,
-                       "altitude": "151.2",
-                       "longitude": "8.49543571448",
-                       "exact_location": 1,
-                       "latitude": "50.55591005174",
-                       "indoor": 0,
-                       "country": "DE"
-               },
-               "sensordatavalues": [
-                       {
-                               "id": 2237722004,
-                               "value_type": "temperature",
-                               "value": "21.45"
-                       },
-                       {
-                               "id": 2237722008,
-                               "value_type": "pressure",
-                               "value": "100205.09"
-                       },
-                       {
-                               "id": 2237722009,
-                               "value_type": "humidity",
-                               "value": "58.79"
-                       },
-                       {
-                               "value_type": "pressure_at_sealevel",
-                               "value": 101974.29
-                       }
-               ]
-       }
-]
\ No newline at end of file
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
deleted file mode 100644 (file)
index 04d75b4..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-       "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
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/noise-result.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/noise-result.json
deleted file mode 100644 (file)
index 053f7bd..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-[
-       {
-               "timestamp": "2020-06-11 09:39:51",
-               "sensordatavalues": [
-                       {
-                               "value": "50.95",
-                               "id": 1629930130,
-                               "value_type": "noise_LAeq"
-                       },
-                       {
-                               "value": "47.20",
-                               "id": 1629930131,
-                               "value_type": "noise_LA_min"
-                       },
-                       {
-                               "value": "56.95",
-                               "id": 1629930132,
-                               "value_type": "noise_LA_max"
-                       }
-               ],
-               "sampling_rate": null,
-               "location": {
-                       "exact_location": 1,
-                       "latitude": "50.88827895000",
-                       "country": "DE",
-                       "altitude": "294.9",
-                       "indoor": 0,
-                       "longitude": "7.87451286686",
-                       "id": 25429
-               },
-               "id": 757217220,
-               "sensor": {
-                       "sensor_type": {
-                               "id": 29,
-                               "manufacturer": "Luftdaten.info",
-                               "name": "Laerm"
-                       },
-                       "pin": "15",
-                       "id": 39745
-               }
-       },
-       {
-               "timestamp": "2020-06-11 09:37:25",
-               "sensordatavalues": [
-                       {
-                               "value": "52.02",
-                               "id": 1629881984,
-                               "value_type": "noise_LAeq"
-                       },
-                       {
-                               "value": "45.98",
-                               "id": 1629881986,
-                               "value_type": "noise_LA_min"
-                       },
-                       {
-                               "value": "69.28",
-                               "id": 1629881987,
-                               "value_type": "noise_LA_max"
-                       }
-               ],
-               "sampling_rate": null,
-               "location": {
-                       "exact_location": 1,
-                       "latitude": "50.88827895000",
-                       "country": "DE",
-                       "altitude": "294.9",
-                       "indoor": 0,
-                       "longitude": "7.87451286686",
-                       "id": 25429
-               },
-               "id": 757194885,
-               "sensor": {
-                       "sensor_type": {
-                               "id": 29,
-                               "manufacturer": "Luftdaten.info",
-                               "name": "Laerm"
-                       },
-                       "pin": "15",
-                       "id": 39745
-               }
-       }
-]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/pm-result.json b/bundles/org.openhab.binding.luftdateninfo/src/test/resources/pm-result.json
deleted file mode 100644 (file)
index 73e5768..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-[
-       {
-               "timestamp": "2020-06-11 09:40:41",
-               "sensordatavalues": [
-                       {
-                               "value": "5.15",
-                               "id": 1629948185,
-                               "value_type": "P1"
-                       },
-                       {
-                               "value": "2.87",
-                               "id": 1629948191,
-                               "value_type": "P2"
-                       }
-               ],
-               "sampling_rate": null,
-               "location": {
-                       "exact_location": 1,
-                       "latitude": "50.55591005174",
-                       "country": "DE",
-                       "altitude": "151.2",
-                       "indoor": 0,
-                       "longitude": "8.49543571448",
-                       "id": 15975
-               },
-               "id": 757225623,
-               "sensor": {
-                       "sensor_type": {
-                               "id": 14,
-                               "manufacturer": "Nova Fitness",
-                               "name": "SDS011"
-                       },
-                       "pin": "1",
-                       "id": 28842
-               }
-       },
-       {
-               "timestamp": "2020-06-11 09:38:16",
-               "sensordatavalues": [
-                       {
-                               "value": "2.20",
-                               "id": 1629900061,
-                               "value_type": "P1"
-                       },
-                       {
-                               "value": "2.00",
-                               "id": 1629900063,
-                               "value_type": "P2"
-                       }
-               ],
-               "sampling_rate": null,
-               "location": {
-                       "exact_location": 1,
-                       "latitude": "50.55591005174",
-                       "country": "DE",
-                       "altitude": "151.2",
-                       "indoor": 0,
-                       "longitude": "8.49543571448",
-                       "id": 15975
-               },
-               "id": 757203291,
-               "sensor": {
-                       "sensor_type": {
-                               "id": 14,
-                               "manufacturer": "Nova Fitness",
-                               "name": "SDS011"
-                       },
-                       "pin": "1",
-                       "id": 28842
-               }
-       }
-]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.sensorcommunity/NOTICE b/bundles/org.openhab.binding.sensorcommunity/NOTICE
new file mode 100644 (file)
index 0000000..38d625e
--- /dev/null
@@ -0,0 +1,13 @@
+This content is produced and maintained by the openHAB project.
+
+* Project home: https://www.openhab.org
+
+== Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License 2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0/.
+
+== Source Code
+
+https://github.com/openhab/openhab-addons
diff --git a/bundles/org.openhab.binding.sensorcommunity/README.md b/bundles/org.openhab.binding.sensorcommunity/README.md
new file mode 100644 (file)
index 0000000..7e93d76
--- /dev/null
@@ -0,0 +1,121 @@
+# SensorCommunity Binding
+
+Binding for the [Sensor.Community](https://sensor.community/).
+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.
+
+## Supported Things
+
+Three Things are supported
+
+| Name               | Thing Type ID | Description                                                                                            |
+|--------------------|---------------|--------------------------------------------------------------------------------------------------------|
+| Particulate Sensor | particulate   | measure particulate matter PM2.5 and PM10                                                              |
+| Conditions Sensor  | condition     | measures environment conditions like temperature, humidity and some also provides atmospheric pressure |
+| Noise Sensor       | noise         | measures noise exposures in the environment                                                            |
+
+## Discovery
+
+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.
+
+![Sensor.Community Logo](doc/local-sensor.png)
+
+### External Sensor
+
+Perform the following steps to get the appropriate Sensor ID
+
+- Go to to [Sensor.Community map](https://deutschland.maps.sensor.community/)
+- Choose your desired value in bottom list - now only the Sensors are displayed which are supporting this
+- Click on your / any Sensor and the ID is displayed in the top right corner. Note: Sensor ID is just the number without beginning hash #
+- Enter this Sensor ID into the thing configuration
+
+![Sensor.Community Logo](doc/SensorCommunity-Map.png)
+
+## Channels
+
+### Particulate Sensor
+
+| Channel ID           | Item Type            | Description                              |
+|----------------------|----------------------|------------------------------------------|
+| pm25                 | Number:Density       | [Ultrafine particulates](https://en.wikipedia.org/wiki/Particulates#Size,_shape_and_solubility_matter) microgram per cubic meter |
+| pm100                | Number:Density       | [Coarse particulate matter](https://en.wikipedia.org/wiki/Particulates#Size,_shape_and_solubility_matter) microgram per cubic meter  |
+
+### Conditions Sensor
+
+| Channel ID           | Item Type            | Description                              |
+|----------------------|----------------------|------------------------------------------|
+| temperature          | Number:Temperature   | current temperature                      |
+| humidity             | Number:Dimensionless | current humidity percent                 |
+| pressure             | Number:Pressure      | Atmospheric Pressure (not supported by all sensors) |
+| pressure-sea         | Number:Pressure      | Atmospheric Pressure on sea level (not supported by all sensors)  |
+
+### Noise Sensor
+
+| Channel ID           | Item Type            | Description                                          |
+|----------------------|----------------------|------------------------------------------------------|
+| noise-eq             | Number:Dimensionless | Average noise in db                                  |
+| noise-min            | Number:Dimensionless | Minimum noise covered in the last 2.5 minutes in db  |
+| noise-main           | Number:Dimensionless | Maximum noise covered in the last 2.5 minutes in db  |
+
+## Full Example
+
+### Things
+
+sensorcommunity.things
+
+```java
+Thing sensorcommunity:particulate:pm_sensor   "PM Sensor"         [ ipAddress=192.168.178.50 ]
+Thing sensorcommunity:conditions:cond_sensor  "Condition Sensor"  [ sensorid=28843 ]
+Thing sensorcommunity:noise:noise_sensor      "Noise Sensor"      [ sensorid=39745 ]
+```
+
+### Items
+
+sensorcommunity.items
+
+```java
+Number:Density PM_25                "PM2.5"                 { channel="sensorcommunity:particulate:pm_sensor:pm25" } 
+Number:Density PM_100               "PM10"                  { channel="sensorcommunity:particulate:pm_sensor:pm100" } 
+
+Number:Temperature LDI_Temperature  "Temperature"           { channel="sensorcommunity:conditions:cond_sensor:temperature" } 
+Number:Dimensionless LDI_Humidity   "Humidity"              { channel="sensorcommunity:conditions:cond_sensor:humidity" } 
+Number:Pressure LDI_Pressure        "Atmospheric Pressure"  { channel="sensorcommunity:conditions:cond_sensor:pressure" } 
+Number:Pressure LDI_PressureSea     "Pressure sea level"    { channel="sensorcommunity:conditions:cond_sensor:pressure-sea" } 
+
+Number:Dimensionless LDI_NoiseEQ    "Noise EQ"              { channel="sensorcommunity:noise:noise_sensor:noise-eq" } 
+Number:Dimensionless LDI_NoiseMin   "Noise min"             { channel="sensorcommunity:noise:noise_sensor:noise-min" } 
+Number:Dimensionless LDI_NoiseMax   "Noise max"             { channel="sensorcommunity:noise:noise_sensor:noise-max" } 
+```
+
+### Sitemap
+
+SensorCommunity.sitemap
+
+```perl
+sitemap SensorCommunity label="SensorCommunity" {
+        Text item=PM_25                     label="Particulate Matter 2.5 [%.1f %unit%]"    
+        Text item=PM_100                    label="Particulate Matter 10 [%.1f %unit%]"     
+
+        Text item=LDI_Temperature           label="Temperature [%d %unit%]"     
+        Text item=LDI_Humidity              label="Humidity [%d %unit%]"    
+        Text item=LDI_Pressure              label="Atmospheric Pressure [%d %unit%]"    
+        Text item=LDI_PressureSea           label="Atmospheric Pressure sea [%d %unit%]"    
+                                            
+        Text item=LDI_NoiseEQ               label="Noise avg [%.1f %unit%]"     
+        Text item=LDI_NoiseMin              label="Noise min [%.1f %unit%]"     
+        Text item=LDI_NoiseMax              label="Noise max [%.1f %unit%]"     
+}
+```
diff --git a/bundles/org.openhab.binding.sensorcommunity/doc/SensorCommunity-Map.png b/bundles/org.openhab.binding.sensorcommunity/doc/SensorCommunity-Map.png
new file mode 100644 (file)
index 0000000..faa378d
Binary files /dev/null and b/bundles/org.openhab.binding.sensorcommunity/doc/SensorCommunity-Map.png differ
diff --git a/bundles/org.openhab.binding.sensorcommunity/doc/local-sensor.png b/bundles/org.openhab.binding.sensorcommunity/doc/local-sensor.png
new file mode 100644 (file)
index 0000000..ccf4e6f
Binary files /dev/null and b/bundles/org.openhab.binding.sensorcommunity/doc/local-sensor.png differ
diff --git a/bundles/org.openhab.binding.sensorcommunity/pom.xml b/bundles/org.openhab.binding.sensorcommunity/pom.xml
new file mode 100644 (file)
index 0000000..489668d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.openhab.addons.bundles</groupId>
+    <artifactId>org.openhab.addons.reactor.bundles</artifactId>
+    <version>4.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.openhab.binding.sensorcommunity</artifactId>
+
+  <name>openHAB Add-ons :: Bundles :: Sensor.Community Binding</name>
+
+</project>
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/feature/feature.xml b/bundles/org.openhab.binding.sensorcommunity/src/main/feature/feature.xml
new file mode 100644 (file)
index 0000000..7e84b4a
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="org.openhab.binding.sensorcommunity-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
+       <repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
+
+       <feature name="openhab-binding-sensorcommunity" description="Sensor.Community Binding" version="${project.version}">
+               <feature>openhab-runtime-base</feature>
+               <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.sensorcommunity/${project.version}</bundle>
+       </feature>
+</features>
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityBindingConstants.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityBindingConstants.java
new file mode 100644 (file)
index 0000000..a566efa
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link SensorCommunityBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class SensorCommunityBindingConstants {
+
+    private static final String BINDING_ID = "sensorcommunity";
+
+    // List of all Thing Type UIDs
+    public static final ThingTypeUID THING_TYPE_PARTICULATE = new ThingTypeUID(BINDING_ID, "particulate");
+    public static final ThingTypeUID THING_TYPE_CONDITIONS = new ThingTypeUID(BINDING_ID, "conditions");
+    public static final ThingTypeUID THING_TYPE_NOISE = new ThingTypeUID(BINDING_ID, "noise");
+
+    // List of all Channel ids
+    public static final String PM25_CHANNEL = "pm25";
+    public static final String PM100_CHANNEL = "pm100";
+    public static final String TEMPERATURE_CHANNEL = "temperature";
+    public static final String HUMIDITY_CHANNEL = "humidity";
+    public static final String PRESSURE_CHANNEL = "pressure";
+    public static final String PRESSURE_SEA_CHANNEL = "pressure-sea";
+    public static final String NOISE_EQ_CHANNEL = "noise-eq";
+    public static final String NOISE_MIN_CHANNEL = "noise-min";
+    public static final String NOISE_MAX_CHANNEL = "noise-max";
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityConfiguration.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityConfiguration.java
new file mode 100644 (file)
index 0000000..e49c932
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.sensorcommunity.internal.utils.Constants;
+
+/**
+ * The {@link SensorCommunityConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class SensorCommunityConfiguration {
+
+    public int sensorid = Constants.UNDEF;
+
+    public String ipAddress = Constants.EMPTY;
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityHandlerFactory.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityHandlerFactory.java
new file mode 100644 (file)
index 0000000..ae8a8db
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.handler.ConditionHandler;
+import org.openhab.binding.sensorcommunity.internal.handler.HTTPHandler;
+import org.openhab.binding.sensorcommunity.internal.handler.NoiseHandler;
+import org.openhab.binding.sensorcommunity.internal.handler.PMHandler;
+import org.openhab.core.io.net.http.HttpClientFactory;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.binding.BaseThingHandlerFactory;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link SensorCommunityHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+@Component(configurationPid = "binding.sensorcommunity", service = ThingHandlerFactory.class)
+public class SensorCommunityHandlerFactory extends BaseThingHandlerFactory {
+    protected final Logger logger = LoggerFactory.getLogger(SensorCommunityHandlerFactory.class);
+
+    @Activate
+    public SensorCommunityHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
+        HTTPHandler.init(httpClientFactory.getCommonHttpClient());
+    }
+
+    @Override
+    public boolean supportsThingType(ThingTypeUID thingTypeUID) {
+        return (thingTypeUID.equals(SensorCommunityBindingConstants.THING_TYPE_PARTICULATE)
+                || thingTypeUID.equals(SensorCommunityBindingConstants.THING_TYPE_CONDITIONS)
+                || thingTypeUID.equals(SensorCommunityBindingConstants.THING_TYPE_NOISE));
+    }
+
+    @Override
+    protected @Nullable ThingHandler createHandler(Thing thing) {
+        if (thing.getThingTypeUID().equals(SensorCommunityBindingConstants.THING_TYPE_PARTICULATE)) {
+            return new PMHandler(thing);
+        } else if (thing.getThingTypeUID().equals(SensorCommunityBindingConstants.THING_TYPE_CONDITIONS)) {
+            return new ConditionHandler(thing);
+        } else if (thing.getThingTypeUID().equals(SensorCommunityBindingConstants.THING_TYPE_NOISE)) {
+            return new NoiseHandler(thing);
+        }
+        logger.info("Handler for {} not found", thing.getThingTypeUID());
+        return null;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Location.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Location.java
new file mode 100644 (file)
index 0000000..7b24edb
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.dto;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link SensorCommunity} class definition for Logging identification
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+public class Location {
+    private int id;
+    private String country;
+    private String altitude;
+    private String latitude;
+    private String longitude;
+    private int indoor;
+    @SerializedName("exact_location")
+    private int exactLocation;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getAltitude() {
+        return altitude;
+    }
+
+    public void setAltitude(String altitude) {
+        this.altitude = altitude;
+    }
+
+    public String getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(String latitude) {
+        this.latitude = latitude;
+    }
+
+    public String getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(String longitude) {
+        this.longitude = longitude;
+    }
+
+    public Integer getIndoor() {
+        return indoor;
+    }
+
+    public void setIndoor(int indoor) {
+        this.indoor = indoor;
+    }
+
+    public int getExactLocation() {
+        return exactLocation;
+    }
+
+    public void setExactLocation(int exactLocation) {
+        this.exactLocation = exactLocation;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Sensor.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Sensor.java
new file mode 100644 (file)
index 0000000..fe96f6a
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.dto;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link Sensor} Data Transfer Object
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+public class Sensor {
+    private int id;
+    private String pin;
+    @SerializedName("sensor_type")
+    private SensorType sensorType;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getPin() {
+        return pin;
+    }
+
+    public void setPin(String pin) {
+        this.pin = pin;
+    }
+
+    public SensorType getSensoTypee() {
+        return sensorType;
+    }
+
+    public void setSensorType(SensorType sensorType) {
+        this.sensorType = sensorType;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorData.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorData.java
new file mode 100644 (file)
index 0000000..9e468cc
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.dto;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link SensorData} Data Transfer Object
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+public class SensorData {
+    private long id;
+    private String timestamp;
+    @SerializedName("sampling_rate")
+    private int samplingRate;
+    @SerializedName("sensordatavalues")
+    private List<SensorDataValue> sensorDataValues;
+    private Location location;
+    private Sensor sensor;
+
+    @Override
+    public String toString() {
+        return id + timestamp;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getTimeStamp() {
+        return timestamp;
+    }
+
+    public void setTimeStamp(String timeStamp) {
+        this.timestamp = timeStamp;
+    }
+
+    public int getSamplingRate() {
+        return samplingRate;
+    }
+
+    public void setSamplingRate(int samplingRate) {
+        this.samplingRate = samplingRate;
+    }
+
+    public List<SensorDataValue> getSensorDataValues() {
+        return sensorDataValues;
+    }
+
+    public void setSensorDataValues(List<SensorDataValue> sensorDataValues) {
+        this.sensorDataValues = sensorDataValues;
+    }
+
+    public Location getLocation() {
+        return location;
+    }
+
+    public void setLocation(Location location) {
+        this.location = location;
+    }
+
+    public Sensor getSensor() {
+        return sensor;
+    }
+
+    public void setSensor(Sensor sensor) {
+        this.sensor = sensor;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorDataValue.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorDataValue.java
new file mode 100644 (file)
index 0000000..cf50101
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.dto;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link SensorDataValue} Data Transfer Object
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+public class SensorDataValue {
+    private long id;
+    @SerializedName("value_type")
+    private String valueType;
+    private String value;
+
+    @Override
+    public String toString() {
+        return valueType + ":" + value;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getValueType() {
+        return valueType;
+    }
+
+    public void setValueType(String valueType) {
+        this.valueType = valueType;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorType.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorType.java
new file mode 100644 (file)
index 0000000..2e00ee4
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.dto;
+
+/**
+ * The {@link SensorType} Data Transfer Object
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+public class SensorType {
+    private int id;
+    private String manufacturer;
+    private String name;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getManufacturer() {
+        return manufacturer;
+    }
+
+    public void setManufacturer(String manufacturer) {
+        this.manufacturer = manufacturer;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/BaseSensorHandler.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/BaseSensorHandler.java
new file mode 100644 (file)
index 0000000..58b462f
--- /dev/null
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.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.sensorcommunity.internal.SensorCommunityConfiguration;
+import org.openhab.binding.sensorcommunity.internal.utils.Constants;
+import org.openhab.binding.sensorcommunity.internal.utils.DateTimeUtils;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link PMHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public abstract class BaseSensorHandler extends BaseThingHandler {
+    private static final SensorCommunityConfiguration DEFAULT_CONFIG = new SensorCommunityConfiguration();
+    private static final String EMPTY = "";
+
+    protected static final int REFRESH_INTERVAL_MIN = 5;
+    protected final Logger logger = LoggerFactory.getLogger(BaseSensorHandler.class);
+    protected SensorCommunityConfiguration config = DEFAULT_CONFIG;
+    protected ConfigStatus configStatus = ConfigStatus.UNKNOWN;
+    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 {
+        INTERNAL_SENSOR_OK,
+        EXTERNAL_SENSOR_OK,
+        IS_NULL,
+        SENSOR_IS_NULL,
+        SENSOR_ID_NEGATIVE,
+        UNKNOWN
+    };
+
+    public enum UpdateStatus {
+        OK,
+        CONNECTION_ERROR,
+        CONNECTION_EXCEPTION,
+        VALUE_ERROR,
+        VALUE_EMPTY,
+        UNKNOWN
+    }
+
+    protected LifecycleStatus lifecycleStatus = LifecycleStatus.UNKNOWN;
+
+    public enum LifecycleStatus {
+        UNKNOWN,
+        RUNNING,
+        INITIALIZING,
+        DISPOSED
+    }
+
+    public BaseSensorHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+        if (command instanceof RefreshType) {
+            updateFromCache();
+        }
+    }
+
+    @Override
+    public void initialize() {
+        firstUpdate = true;
+        lifecycleStatus = LifecycleStatus.INITIALIZING;
+        scheduler.execute(this::startUp);
+    }
+
+    private void startUp() {
+        config = getConfigAs(SensorCommunityConfiguration.class);
+        configStatus = checkConfig(config);
+        if (configStatus == ConfigStatus.INTERNAL_SENSOR_OK || configStatus == ConfigStatus.EXTERNAL_SENSOR_OK) {
+            // start getting values
+            dataUpdate();
+        } else {
+            // config error, no further actions triggered - Thing Status visible in UI
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+                    "Configuration not valid. Sensor ID as a number is mandatory!");
+        }
+        lifecycleStatus = LifecycleStatus.RUNNING;
+    }
+
+    private void startSchedule() {
+        ScheduledFuture<?> localRefreshJob = refreshJob;
+        if (localRefreshJob != null) {
+            if (localRefreshJob.isCancelled()) {
+                refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 5, REFRESH_INTERVAL_MIN,
+                        TimeUnit.MINUTES);
+            } // else - scheduler is already running!
+        } else {
+            refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 5, REFRESH_INTERVAL_MIN, TimeUnit.MINUTES);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        ScheduledFuture<?> localRefreshJob = refreshJob;
+        if (localRefreshJob != null) {
+            localRefreshJob.cancel(true);
+        }
+        lifecycleStatus = LifecycleStatus.DISPOSED;
+    }
+
+    /**
+     * Checks if config is valid - a) not null and b) sensorid is a number
+     *
+     * @param c
+     * @return
+     */
+    private ConfigStatus checkConfig(@Nullable SensorCommunityConfiguration c) {
+        if (c != null) {
+            if (c.ipAddress != null && !Constants.EMPTY.equals(c.ipAddress)) {
+                sensorUrl = Optional.of("http://" + c.ipAddress + "/data.json");
+                return ConfigStatus.INTERNAL_SENSOR_OK;
+            } else {
+                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;
+        }
+    }
+
+    public LifecycleStatus getLifecycleStatus() {
+        return lifecycleStatus;
+    }
+
+    protected void dataUpdate() {
+        if (sensorUrl.isPresent()) {
+            HTTPHandler.getHandler().request(sensorUrl.get(), this);
+        }
+    }
+
+    public void onResponse(String 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);
+    }
+
+    public void onError(String errorReason) {
+        statusUpdate(UpdateStatus.CONNECTION_EXCEPTION,
+                errorReason + " / " + LocalDateTime.now().format(DateTimeUtils.DTF));
+    }
+
+    protected void statusUpdate(UpdateStatus updateStatus, String details) {
+        if (updateStatus == UpdateStatus.OK) {
+            updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
+            startSchedule();
+        } else {
+            switch (updateStatus) {
+                case CONNECTION_ERROR:
+                    // start job even first update delivers no data - recovery is possible
+                    startSchedule();
+                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+                            "Update failed due to Connection error. Trying to recover in next refresh");
+                    break;
+                case CONNECTION_EXCEPTION:
+                    // start job even first update delivers a Connection Exception - recovery is possible
+                    startSchedule();
+                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, details);
+                    break;
+                case VALUE_EMPTY:
+                    // start job even if first update delivers no values - recovery possible
+                    startSchedule();
+                    updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE,
+                            "No values delivered by Sensor. Trying to recover in next refresh");
+                    break;
+                case VALUE_ERROR:
+                    // final status - values from sensor are wrong and manual check is needed
+                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+                            "Sensor values doesn't match - please check if Sensor ID is delivering the correct Thing channel values");
+                    break;
+                default:
+                    // final status - Configuration is wrong
+                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+                            "Error during update - please check your config data");
+                    break;
+            }
+        }
+    }
+
+    @Override
+    protected void updateStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String description) {
+        myThingStatus = status;
+        super.updateStatus(status, statusDetail, description);
+    }
+
+    protected abstract UpdateStatus updateChannels(@Nullable String json);
+
+    protected abstract void updateFromCache();
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/ConditionHandler.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/ConditionHandler.java
new file mode 100644 (file)
index 0000000..e114c1e
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.handler;
+
+import static org.openhab.binding.sensorcommunity.internal.SensorCommunityBindingConstants.*;
+import static org.openhab.binding.sensorcommunity.internal.utils.Constants.*;
+import static org.openhab.core.library.unit.MetricPrefix.HECTO;
+
+import java.util.List;
+
+import javax.measure.quantity.Dimensionless;
+import javax.measure.quantity.Pressure;
+import javax.measure.quantity.Temperature;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.utils.NumberUtils;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Thing;
+
+/**
+ * The {@link ConditionHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@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, HECTO(SIUnits.PASCAL));
+    protected QuantityType<Pressure> pressureSeaCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL));
+
+    public ConditionHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    public UpdateStatus updateChannels(@Nullable String json) {
+        if (json != null) {
+            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
+            if (valueList != null) {
+                if (HTTPHandler.getHandler().isCondition(valueList)) {
+                    valueList.forEach(v -> {
+                        if (v.getValueType().endsWith(TEMPERATURE)) {
+                            temperatureCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
+                                    SIUnits.CELSIUS);
+                            updateState(TEMPERATURE_CHANNEL, temperatureCache);
+                        } else if (v.getValueType().endsWith(HUMIDITY)) {
+                            humidityCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.PERCENT);
+                            updateState(HUMIDITY_CHANNEL, humidityCache);
+                        } 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().endsWith(PRESSURE_SEALEVEL)) {
+                            pressureSeaCache = QuantityType.valueOf(
+                                    NumberUtils.round(NumberUtils.convert(v.getValue()) / 100, 1),
+                                    HECTO(SIUnits.PASCAL));
+                            updateState(PRESSURE_SEA_CHANNEL, pressureSeaCache);
+                        }
+                    });
+                    return UpdateStatus.OK;
+                } else {
+                    return UpdateStatus.VALUE_ERROR;
+                }
+            } else {
+                return UpdateStatus.VALUE_EMPTY;
+            }
+        } else {
+            return UpdateStatus.CONNECTION_ERROR;
+        }
+    }
+
+    @Override
+    protected void updateFromCache() {
+        updateState(TEMPERATURE_CHANNEL, temperatureCache);
+        updateState(HUMIDITY_CHANNEL, humidityCache);
+        updateState(PRESSURE_CHANNEL, pressureCache);
+        updateState(PRESSURE_SEA_CHANNEL, pressureSeaCache);
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/HTTPHandler.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/HTTPHandler.java
new file mode 100644 (file)
index 0000000..75ecf8f
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.handler;
+
+import static org.openhab.binding.sensorcommunity.internal.utils.Constants.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.BufferingResponseListener;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorData;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.utils.DateTimeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+
+/**
+ * The {@link HTTPHandler} is responsible for HTTP requests and JSON handling
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class HTTPHandler {
+    private final Logger logger = LoggerFactory.getLogger(HTTPHandler.class);
+
+    private static final Gson GSON = new Gson();
+    private static final HTTPHandler HTTP_HANDLER = new HTTPHandler();
+
+    private static @Nullable HttpClient commonHttpClient;
+
+    public static void init(HttpClient httpClient) {
+        commonHttpClient = httpClient;
+    }
+
+    public static HTTPHandler getHandler() {
+        return HTTP_HANDLER;
+    }
+
+    public synchronized void request(String url, BaseSensorHandler callback) {
+        HttpClient localClient = commonHttpClient;
+        if (localClient == null) {
+            logger.warn("HTTP Client not initialized");
+        } else {
+            Request req = localClient.newRequest(url);
+            req.timeout(15, TimeUnit.SECONDS).send(new BufferingResponseListener() {
+                @NonNullByDefault({})
+                @Override
+                public void onComplete(org.eclipse.jetty.client.api.Result result) {
+                    if (result.getResponse().getStatus() != 200) {
+                        String failure;
+                        if (result.getResponse().getReason() != null) {
+                            failure = result.getResponse().getReason();
+                        } else {
+                            failure = result.getFailure().getMessage();
+                        }
+                        callback.onError(Objects.requireNonNullElse(failure, "Unknown error"));
+                    } else {
+                        callback.onResponse(getContentAsString());
+                    }
+                }
+            });
+        }
+    }
+
+    public @Nullable List<SensorDataValue> getLatestValues(String response) {
+        SensorData[] valueArray = GSON.fromJson(response, SensorData[].class);
+        if (valueArray.length == 0) {
+            return null;
+        } else if (valueArray.length == 1) {
+            SensorData v = valueArray[0];
+            return v.getSensorDataValues();
+        } else if (valueArray.length > 1) {
+            // declare first item as latest
+            SensorData latestData = valueArray[0];
+            String latestTimeStr = latestData.getTimeStamp();
+            LocalDateTime latestTime = DateTimeUtils.toDate(latestTimeStr);
+            if (latestTime == null) {
+                logDateConversionError(response, latestData);
+            }
+            for (int i = 1; i < valueArray.length; i++) {
+                SensorData iterData = valueArray[i];
+                String iterTimeStr = iterData.getTimeStamp();
+                LocalDateTime iterTime = DateTimeUtils.toDate(iterTimeStr);
+                if (iterTime == null) {
+                    logDateConversionError(response, latestData);
+                }
+                if (iterTime != null && latestTime != null) {
+                    if (latestTime.isBefore(iterTime)) {
+                        // found item is newer - take it as latest
+                        latestTime = iterTime;
+                        latestData = iterData;
+                    } // else - found item is older - nothing to do
+
+                } else {
+                    logger.warn("One or two dates cannot be decoded 1) {} 2) {}", iterTimeStr, latestTimeStr);
+                }
+            }
+            return latestData.getSensorDataValues();
+        } else {
+            return null;
+        }
+    }
+
+    public void logDateConversionError(final String response, final Object dto) {
+        logger.warn("Unable to get timestamp");
+        logger.warn("Response: {}", response);
+        String json = GSON.toJson(dto);
+        logger.warn("GSon: {}", json);
+    }
+
+    public boolean isParticulate(@Nullable List<SensorDataValue> valueList) {
+        if (valueList == null) {
+            return false;
+        }
+        return valueList.stream().map(v -> v.getValueType()).filter(t -> t.endsWith(P1) || t.endsWith(P2)).findAny()
+                .isPresent();
+    }
+
+    public boolean isCondition(@Nullable List<SensorDataValue> valueList) {
+        if (valueList == null) {
+            return false;
+        }
+        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) {
+        if (valueList == null) {
+            return false;
+        }
+        return valueList.stream().map(v -> v.getValueType())
+                .filter(t -> t.endsWith(NOISE_EQ) || t.endsWith(NOISE_MAX) || t.endsWith(NOISE_MIN)).findAny()
+                .isPresent();
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/NoiseHandler.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/NoiseHandler.java
new file mode 100644 (file)
index 0000000..1eb882b
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.handler;
+
+import static org.openhab.binding.sensorcommunity.internal.SensorCommunityBindingConstants.*;
+import static org.openhab.binding.sensorcommunity.internal.utils.Constants.*;
+
+import java.util.List;
+
+import javax.measure.quantity.Dimensionless;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.utils.NumberUtils;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Thing;
+
+/**
+ * The {@link NoiseHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class NoiseHandler extends BaseSensorHandler {
+    protected QuantityType<Dimensionless> noiseEQCache = QuantityType.valueOf(-1, Units.DECIBEL);
+    protected QuantityType<Dimensionless> noiseMinCache = QuantityType.valueOf(-1, Units.DECIBEL);
+    protected QuantityType<Dimensionless> noiseMaxCache = QuantityType.valueOf(-1, Units.DECIBEL);
+
+    public NoiseHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    public UpdateStatus updateChannels(@Nullable String json) {
+        if (json != null) {
+            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
+            if (valueList != null) {
+                if (HTTPHandler.getHandler().isNoise(valueList)) {
+                    valueList.forEach(v -> {
+                        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().endsWith(NOISE_MIN)) {
+                            noiseMinCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
+                            updateState(NOISE_MIN_CHANNEL, noiseMinCache);
+                        } else if (v.getValueType().endsWith(NOISE_MAX)) {
+                            noiseMaxCache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1), Units.DECIBEL);
+                            updateState(NOISE_MAX_CHANNEL, noiseMaxCache);
+                        }
+                    });
+                    return UpdateStatus.OK;
+                } else {
+                    return UpdateStatus.VALUE_ERROR;
+                }
+            } else {
+                return UpdateStatus.VALUE_EMPTY;
+            }
+        } else {
+            return UpdateStatus.CONNECTION_ERROR;
+        }
+    }
+
+    @Override
+    protected void updateFromCache() {
+        updateState(NOISE_EQ_CHANNEL, noiseEQCache);
+        updateState(NOISE_MIN_CHANNEL, noiseMinCache);
+        updateState(NOISE_MAX_CHANNEL, noiseMaxCache);
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/PMHandler.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/PMHandler.java
new file mode 100644 (file)
index 0000000..ff58d97
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.handler;
+
+import static org.openhab.binding.sensorcommunity.internal.SensorCommunityBindingConstants.*;
+import static org.openhab.binding.sensorcommunity.internal.utils.Constants.*;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.utils.NumberUtils;
+import org.openhab.core.library.dimension.Density;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Thing;
+
+/**
+ * The {@link PMHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class PMHandler extends BaseSensorHandler {
+
+    protected QuantityType<Density> pm25Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE);
+    protected QuantityType<Density> pm100Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE);
+
+    public PMHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    public UpdateStatus updateChannels(@Nullable String json) {
+        if (json != null) {
+            List<SensorDataValue> valueList = HTTPHandler.getHandler().getLatestValues(json);
+            if (valueList != null) {
+                if (HTTPHandler.getHandler().isParticulate(valueList)) {
+                    valueList.forEach(v -> {
+                        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().endsWith(P2)) {
+                            pm25Cache = QuantityType.valueOf(NumberUtils.round(v.getValue(), 1),
+                                    Units.MICROGRAM_PER_CUBICMETRE);
+                            updateState(PM25_CHANNEL, pm25Cache);
+                        }
+                    });
+                    return UpdateStatus.OK;
+                } else {
+                    return UpdateStatus.VALUE_ERROR;
+                }
+            } else {
+                return UpdateStatus.VALUE_EMPTY;
+            }
+        } else {
+            return UpdateStatus.CONNECTION_ERROR;
+        }
+    }
+
+    @Override
+    protected void updateFromCache() {
+        updateState(PM25_CHANNEL, pm25Cache);
+        updateState(PM100_CHANNEL, pm100Cache);
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/Constants.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/Constants.java
new file mode 100644 (file)
index 0000000..69ed677
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.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;
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/DateTimeUtils.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/DateTimeUtils.java
new file mode 100644 (file)
index 0000000..de79e6d
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.utils;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.Locale;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DateTimeUtils} class provides helpers for converting Dates and Times.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class DateTimeUtils {
+    public static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
+    private static final Logger LOGGER = LoggerFactory.getLogger(DateTimeUtils.class);
+
+    public static synchronized @Nullable LocalDateTime toDate(String dateTime) {
+        try {
+            return LocalDateTime.from(DTF.parse(dateTime));
+
+        } catch (DateTimeParseException e) {
+            LOGGER.debug("Unable to parse date {}", dateTime);
+            return null;
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/NumberUtils.java b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/NumberUtils.java
new file mode 100644 (file)
index 0000000..cf8ef3b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.utils;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link NumberUtils} class provides helpers for converting Numbers.
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class NumberUtils {
+    public static final double UNDEF = Double.NaN;
+
+    public static double round(Object o, int places) {
+        double value = convert(o);
+
+        // for negative places return plain number
+        if (places < 0) {
+            return value;
+        }
+
+        long factor = (long) Math.pow(10, places);
+        value = value * factor;
+        long tmp = Math.round(value);
+        return (double) tmp / factor;
+    }
+
+    public static double convert(Object o) {
+        // ensure value not null
+        double value = UNDEF;
+        if (o instanceof Number) {
+            value = ((Number) o).doubleValue();
+        } else if (o instanceof String) {
+            value = Double.parseDouble(o.toString());
+        }
+        return value;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/addon/addon.xml b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/addon/addon.xml
new file mode 100644 (file)
index 0000000..b190653
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<addon:addon id="sensorcommunity" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
+
+       <type>binding</type>
+       <name>Sensor.Community Binding</name>
+       <description>Binding to integrate DIY Sensors from Sensor.Community</description>
+       <connection>hybrid</connection>
+
+</addon:addon>
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity.properties b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity.properties
new file mode 100644 (file)
index 0000000..cb1e4ea
--- /dev/null
@@ -0,0 +1,47 @@
+# add-on
+
+addon.sensorcommunity.name = Sensor.Community Binding
+addon.sensorcommunity.description = Binding to integrate DIY Sensors from Sensor.Community
+
+# thing types
+
+thing-type.sensorcommunity.conditions.label = Condition Sensor
+thing-type.sensorcommunity.conditions.description = Sensor to measure Temperature and Humidity conditions
+thing-type.sensorcommunity.noise.label = Noise Sensor
+thing-type.sensorcommunity.noise.description = Sensor to measure noise on location
+thing-type.sensorcommunity.particulate.label = Particulate Sensor
+thing-type.sensorcommunity.particulate.description = Sensor to measure Particulate Matter (PM)
+
+# thing types config
+
+thing-type.config.sensorcommunity.conditions.ipAddress.label = Internal IP Address
+thing-type.config.sensorcommunity.conditions.ipAddress.description = Local IP address of your personal owned sensor
+thing-type.config.sensorcommunity.conditions.sensorid.label = External Sensor ID
+thing-type.config.sensorcommunity.conditions.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
+thing-type.config.sensorcommunity.noise.ipAddress.label = Internal IP Address
+thing-type.config.sensorcommunity.noise.ipAddress.description = Local IP address of your personal owned sensor
+thing-type.config.sensorcommunity.noise.sensorid.label = External Sensor ID
+thing-type.config.sensorcommunity.noise.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
+thing-type.config.sensorcommunity.particulate.ipAddress.label = Internal IP Address
+thing-type.config.sensorcommunity.particulate.ipAddress.description = Local IP address of your personal owned sensor
+thing-type.config.sensorcommunity.particulate.sensorid.label = External Sensor ID
+thing-type.config.sensorcommunity.particulate.sensorid.description = Sensor ID from https://deutschland.maps.sensor.community/
+
+# channel types
+
+channel-type.sensorcommunity.hum-channel.label = Humidity
+channel-type.sensorcommunity.hum-channel.description = Humidity from the selected Sensor ID
+channel-type.sensorcommunity.noise-eq-channel.label = Average Noise
+channel-type.sensorcommunity.noise-eq-channel.description = Average noise level from the selected Sensor ID
+channel-type.sensorcommunity.noise-max-channel.label = Maximum Noise
+channel-type.sensorcommunity.noise-max-channel.description = Maximum noise level (last 2.5 minutes) from the selected Sensor ID
+channel-type.sensorcommunity.noise-min-channel.label = Minimum Noise
+channel-type.sensorcommunity.noise-min-channel.description = Minimum noise level (last 2.5 minutes) from the selected Sensor ID
+channel-type.sensorcommunity.pm100-channel.label = Particulate Matter category 10.0
+channel-type.sensorcommunity.pm25-channel.label = Particulate Matter category 2.5
+channel-type.sensorcommunity.pressure-channel.label = Atmospheric Pressure
+channel-type.sensorcommunity.pressure-channel.description = Atmospheric Pressure from the selected Sensor ID
+channel-type.sensorcommunity.pressure-sea-channel.label = Atmospheric Pressure Sea Level
+channel-type.sensorcommunity.pressure-sea-channel.description = Atmospheric Pressure at sea level from the selected Sensor ID
+channel-type.sensorcommunity.temp-channel.label = Temperature
+channel-type.sensorcommunity.temp-channel.description = Temperature from the selected Sensor ID
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity_de.properties b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity_de.properties
new file mode 100644 (file)
index 0000000..b7b800f
--- /dev/null
@@ -0,0 +1,47 @@
+# add-on
+
+addon.sensorcommunity.name = Sensor.Community Binding
+addon.sensorcommunity.description = Das Binding stellt die Daten der Eigenbau-Sensoren von Sensor.Community zur Verfügung
+
+# thing types
+
+thing-type.sensorcommunity.conditions.label = Umweltsensor
+thing-type.sensorcommunity.conditions.description = Messung der Temperatur, Luftfeuchtigkeit und Luftdruck 
+thing-type.sensorcommunity.noise.label = Lärmsensor
+thing-type.sensorcommunity.noise.description = Messung der Lärmbelastung in der Umgebung 
+thing-type.sensorcommunity.particulate.label = Feinstaubsensor
+thing-type.sensorcommunity.particulate.description = Messung der Feinstaubbelastung in der Umgebung 
+
+# thing types config
+
+thing-type.config.sensorcommunity.conditions.ipAddress.label = Interne IP-Adresse
+thing-type.config.sensorcommunity.conditions.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
+thing-type.config.sensorcommunity.conditions.sensorid.label = Externe Sensor-ID
+thing-type.config.sensorcommunity.conditions.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
+thing-type.config.sensorcommunity.noise.ipAddress.label = Interne IP-Adresse
+thing-type.config.sensorcommunity.noise.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
+thing-type.config.sensorcommunity.noise.sensorid.label = Externe Sensor-ID
+thing-type.config.sensorcommunity.noise.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
+thing-type.config.sensorcommunity.particulate.ipAddress.label = Interne IP-Adresse
+thing-type.config.sensorcommunity.particulate.ipAddress.description = Lokale IP-Adresse Ihres persönlichen Sensors
+thing-type.config.sensorcommunity.particulate.sensorid.label = Externe Sensor-ID
+thing-type.config.sensorcommunity.particulate.sensorid.description = Sensor-ID von https\://deutschland.maps.sensor.community/
+
+# channel types
+
+channel-type.sensorcommunity.hum-channel.label = Luftfeuchtigkeit
+channel-type.sensorcommunity.hum-channel.description = Luftfeuchtigkeit der ausgewählten Sensor-ID
+channel-type.sensorcommunity.noise-eq-channel.label = Durchschnittlicher Lärmpegel
+channel-type.sensorcommunity.noise-eq-channel.description = Durchschnittlicher Rauschpegel der ausgewählten Sensor-ID
+channel-type.sensorcommunity.noise-max-channel.label = Maximaler Lärmpegel 
+channel-type.sensorcommunity.noise-max-channel.description = Maximaler Rauschpegel (letzte 2,5 Minuten) der ausgewählten Sensor-ID
+channel-type.sensorcommunity.noise-min-channel.label = Minimaler Lärmpegel 
+channel-type.sensorcommunity.noise-min-channel.description = Minimaler Rauschpegel (letzte 2,5 Minuten) der ausgewählten Sensor-ID
+channel-type.sensorcommunity.pm100-channel.label = Feinstaub der Kategorie PM 10.0
+channel-type.sensorcommunity.pm25-channel.label = Feinstaub der Kategorie PM 2.5
+channel-type.sensorcommunity.pressure-channel.label = Atmosphärischer Druck
+channel-type.sensorcommunity.pressure-channel.description = Atmosphärischer Druck der ausgewählten Sensor-ID
+channel-type.sensorcommunity.pressure-sea-channel.label = Atmosphärischer Druck Auf Meereshöhe
+channel-type.sensorcommunity.pressure-sea-channel.description = Atmosphärischer Druck auf Seehöhe der ausgewählten Sensor-ID
+channel-type.sensorcommunity.temp-channel.label = Temperatur
+channel-type.sensorcommunity.temp-channel.description = Temperatur der ausgewählten Sensor-ID
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/thing/thing-types.xml
new file mode 100644 (file)
index 0000000..89684f8
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="sensorcommunity"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="particulate">
+               <label>Particulate Sensor</label>
+               <description>Sensor to measure Particulate Matter (PM)</description>
+
+               <channels>
+                       <channel id="pm25" typeId="pm25-channel"/>
+                       <channel id="pm100" typeId="pm100-channel"/>
+               </channels>
+
+               <config-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>
+
+       <thing-type id="conditions">
+               <label>Condition Sensor</label>
+               <description>Sensor to measure Temperature and Humidity conditions</description>
+
+               <channels>
+                       <channel id="temperature" typeId="temp-channel"/>
+                       <channel id="humidity" typeId="hum-channel"/>
+                       <channel id="pressure" typeId="pressure-channel"/>
+                       <channel id="pressure-sea" typeId="pressure-sea-channel"/>
+               </channels>
+
+               <config-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>
+
+       <thing-type id="noise">
+               <label>Noise Sensor</label>
+               <description>Sensor to measure noise on location</description>
+
+               <channels>
+                       <channel id="noise-eq" typeId="noise-eq-channel"/>
+                       <channel id="noise-min" typeId="noise-min-channel"/>
+                       <channel id="noise-max" typeId="noise-max-channel"/>
+               </channels>
+
+               <config-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>
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/ConditionHandlerTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/ConditionHandlerTest.java
new file mode 100644 (file)
index 0000000..9df8f12
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.openhab.core.library.unit.MetricPrefix.HECTO;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.handler.BaseSensorHandler.UpdateStatus;
+import org.openhab.binding.sensorcommunity.internal.mock.ConditionHandlerExtension;
+import org.openhab.binding.sensorcommunity.internal.mock.ThingMock;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
+
+/**
+ * The {@link ConditionHandlerTest} Test Condition Handler updates
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class ConditionHandlerTest {
+
+    @Test
+    public void testValidNoPressureUpdate() {
+        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);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        if (pmJson != null) {
+            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., 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);
+        }
+    }
+
+    @Test
+    public void testValidWithPressureUpdate() {
+        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);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-plus-pressure.json");
+        if (pmJson != null) {
+            UpdateStatus result = condHandler.updateChannels(pmJson);
+            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(1002.0, HECTO(SIUnits.PASCAL)), condHandler.getPressure(), "Pressure");
+            assertEquals(QuantityType.valueOf(1019.7, HECTO(SIUnits.PASCAL)), condHandler.getPressureSea(),
+                    "Pressure Sea");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testInvalidUpdate() {
+        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);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
+        if (pmJson != null) {
+            UpdateStatus result = condHandler.updateChannels(pmJson);
+            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testEmptyUpdate() {
+        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);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        UpdateStatus result = condHandler.updateChannels("[]");
+        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
+    }
+
+    @Test
+    public void testNullUpdate() {
+        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);
+
+        ConditionHandlerExtension condHandler = new ConditionHandlerExtension(t);
+        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);
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/DTOTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/DTOTest.java
new file mode 100644 (file)
index 0000000..9d9fcfb
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorData;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+import org.openhab.binding.sensorcommunity.internal.utils.Constants;
+
+import com.google.gson.Gson;
+
+/**
+ * The {@link DTOTest} Data Transfer Object - test conversions
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class DTOTest {
+
+    @Test
+    public void testConditions() {
+        String result = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        Gson gson = new Gson();
+        SensorData[] valueArray = gson.fromJson(result, SensorData[].class);
+        // System.out.println(valueArray.length);
+        assertEquals(2, valueArray.length, "Array size");
+
+        SensorData d = valueArray[0];
+        // Assure latest data is taken
+        String dateStr = d.getTimeStamp();
+        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 (Constants.TEMPERATURE.equals(v.getValueType())) {
+                assertEquals("22.70", v.getValue(), "Temperature");
+            } else if (Constants.HUMIDITY.equals(v.getValueType())) {
+                assertEquals("61.00", v.getValue(), "Humidity");
+            }
+        });
+    }
+
+    @Test
+    public void testDecoding() {
+        String result = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        Gson gson = new Gson();
+        SensorData[] valueArray = gson.fromJson(result, SensorData[].class);
+        // System.out.println(valueArray.length);
+        assertEquals(2, valueArray.length, "Array size");
+
+        SensorData d = valueArray[0];
+        // Assure latest data is taken
+        String dateStr = d.getTimeStamp();
+        if (dateStr.equals("2020-06-09 06:38:08")) {
+            // take newer one
+            d = valueArray[1];
+        }
+
+        // test decoding a small part
+        String json = gson.toJson(d);
+        // System.out.println(json);
+        // check if correct timestamp is included
+        assertTrue(json.contains("\"timestamp\":\"2020-06-09 06:40:34\""));
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerEvalTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerEvalTest.java
new file mode 100644 (file)
index 0000000..6f42d6a
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.handler.HTTPHandler;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+
+/**
+ * The {@link HTTPHandlerEvalTest} test all evaluations on SensorDataValues
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class HTTPHandlerEvalTest {
+
+    private @Nullable List<SensorDataValue> conditions;
+    private @Nullable List<SensorDataValue> particulate;
+    private @Nullable List<SensorDataValue> noise;
+    private HTTPHandler http = new HTTPHandler();
+
+    @BeforeEach
+    public void setUp() {
+        String conditionsStr = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        assertNotNull(conditionsStr);
+        Objects.requireNonNull(conditionsStr);
+        conditions = http.getLatestValues(conditionsStr);
+
+        String particulateStr = FileReader.readFileInString("src/test/resources/pm-result.json");
+        assertNotNull(particulateStr);
+        Objects.requireNonNull(particulateStr);
+        particulate = http.getLatestValues(particulateStr);
+
+        String noiseStr = FileReader.readFileInString("src/test/resources/noise-result.json");
+        assertNotNull(noiseStr);
+        Objects.requireNonNull(noiseStr);
+        noise = http.getLatestValues(noiseStr);
+    }
+
+    @Test
+    public void testIsCondition() {
+        assertTrue(http.isCondition(conditions));
+        assertFalse(http.isCondition(particulate));
+        assertFalse(http.isCondition(noise));
+        assertFalse(http.isCondition(null));
+    }
+
+    @Test
+    public void testIsParticulate() {
+        assertFalse(http.isParticulate(conditions));
+        assertTrue(http.isParticulate(particulate));
+        assertFalse(http.isParticulate(noise));
+        assertFalse(http.isParticulate(null));
+    }
+
+    @Test
+    public void testIsNoise() {
+        assertFalse(http.isNoise(conditions));
+        assertFalse(http.isNoise(particulate));
+        assertTrue(http.isNoise(noise));
+        assertFalse(http.isNoise(null));
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerValueTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerValueTest.java
new file mode 100644 (file)
index 0000000..d5a3805
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
+import org.openhab.binding.sensorcommunity.internal.handler.HTTPHandler;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+import org.openhab.binding.sensorcommunity.internal.utils.Constants;
+
+/**
+ * The {@link HTTPHandlerValueTest} test values decoding of HTTPHandler
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class HTTPHandlerValueTest {
+    private HTTPHandler http = new HTTPHandler();
+
+    /**
+     * test if really the latest values are returned
+     * resource1 is json with ordering according to time while resource2 the entries flipped
+     */
+    @Test
+    public void testValueDecoding() {
+        String resource1 = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        assertNotNull(resource1);
+        Objects.requireNonNull(resource1);
+        List<SensorDataValue> l = http.getLatestValues(resource1);
+        assertNotNull(l);
+        Objects.requireNonNull(l);
+        l.forEach(sd -> {
+            testSensorValue(sd);
+        });
+
+        String resource2 = FileReader
+                .readFileInString("src/test/resources/condition-result-no-pressure-flipped-values.json");
+        assertNotNull(resource2);
+        Objects.requireNonNull(resource2);
+        l = http.getLatestValues(resource2);
+        assertNotNull(l);
+        Objects.requireNonNull(l);
+        l.forEach(sd -> {
+            testSensorValue(sd);
+        });
+    }
+
+    private void testSensorValue(SensorDataValue s) {
+        if (s.getValueType().equals(Constants.TEMPERATURE)) {
+            assertEquals("22.70", s.getValue(), "Temperature resource 1");
+        } else if (s.getValueType().equals(Constants.HUMIDITY)) {
+            assertEquals("61.00", s.getValue(), "Humidity resource 1");
+        } else {
+            assertTrue(false);
+        }
+        // System.out.println(s.getValue_type() + ":" + s.getValue());
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NoiseHandlerTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NoiseHandlerTest.java
new file mode 100644 (file)
index 0000000..b1204af
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.handler.BaseSensorHandler.UpdateStatus;
+import org.openhab.binding.sensorcommunity.internal.mock.NoiseHandlerExtension;
+import org.openhab.binding.sensorcommunity.internal.mock.ThingMock;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+
+/**
+ * The {@link NoiseHandlerTest} Test Noise Handler updates
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class NoiseHandlerTest {
+
+    @Test
+    public void testValidUpdate() {
+        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);
+
+        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
+        if (pmJson != null) {
+            UpdateStatus result = noiseHandler.updateChannels(pmJson);
+            assertEquals(UpdateStatus.OK, result, "Valid update");
+            assertEquals(QuantityType.valueOf(51.0, Units.DECIBEL), noiseHandler.getNoiseEQCache(), "Noise EQ");
+            assertEquals(QuantityType.valueOf(47.2, Units.DECIBEL), noiseHandler.getNoiseMinCache(), "Noise Min");
+            assertEquals(QuantityType.valueOf(57.0, Units.DECIBEL), noiseHandler.getNoiseMaxCache(), "Noise Max");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testInvalidUpdate() {
+        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);
+
+        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
+        String pmJson = FileReader.readFileInString("src/test/resources/condition-result-no-pressure.json");
+        if (pmJson != null) {
+            UpdateStatus result = noiseHandler.updateChannels(pmJson);
+            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
+            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseEQCache(), "Values undefined");
+            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseMinCache(), "Values undefined");
+            assertEquals(QuantityType.valueOf(-1, Units.DECIBEL), noiseHandler.getNoiseMaxCache(), "Values undefined");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testEmptyUpdate() {
+        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);
+
+        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
+        UpdateStatus result = noiseHandler.updateChannels("[]");
+        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
+    }
+
+    @Test
+    public void testNullUpdate() {
+        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);
+
+        NoiseHandlerExtension noiseHandler = new NoiseHandlerExtension(t);
+        UpdateStatus result = noiseHandler.updateChannels(null);
+        assertEquals(UpdateStatus.CONNECTION_ERROR, result, "Valid update");
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NumberTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NumberTest.java
new file mode 100644 (file)
index 0000000..a0fb197
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.utils.NumberUtils;
+
+/**
+ * The {@link NumberTest} Test rounding and converting Numbers
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class NumberTest {
+
+    @Test
+    public void testRoundingUp() {
+        double d1 = 1.95;
+        double d1r2 = NumberUtils.round(d1, 2);
+        assertEquals("1.95", Double.toString(d1r2), "Double 1.95, 2 places");
+        // System.out.println("D1R2 " + d1r2);
+        double d1r1 = NumberUtils.round(d1, 1);
+        // System.out.println("D1R1 " + d1r1);
+        assertEquals("2.0", Double.toString(d1r1), "Double 1.95, 1 place");
+    }
+
+    @Test
+    public void testRoundingDown() {
+        double d1 = 1.94;
+        double d1r2 = NumberUtils.round(d1, 2);
+        assertEquals("1.94", Double.toString(d1r2), "Double 1.94, 2 places");
+        // System.out.println("D1R2 " + d1r2);
+        double d1r1 = NumberUtils.round(d1, 1);
+        // System.out.println("D1R1 " + d1r1);
+        assertEquals("1.9", Double.toString(d1r1), "Double 1.94, 1 place");
+    }
+
+    @Test
+    public void testStringNumbers() {
+        String d1 = "1.94";
+        double d1r2 = NumberUtils.round(d1, 2);
+        assertEquals("1.94", Double.toString(d1r2), "Double 1.94, 2 places");
+        // System.out.println("D1R2 " + d1r2);
+        double d1r1 = NumberUtils.round(d1, 1);
+        // System.out.println("D1R1 " + d1r1);
+        assertEquals("1.9", Double.toString(d1r1), "Double 1.94, 1 place");
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/PMHandlerTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/PMHandlerTest.java
new file mode 100644 (file)
index 0000000..2a979e8
--- /dev/null
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.handler.BaseSensorHandler.ConfigStatus;
+import org.openhab.binding.sensorcommunity.internal.handler.BaseSensorHandler.LifecycleStatus;
+import org.openhab.binding.sensorcommunity.internal.handler.BaseSensorHandler.UpdateStatus;
+import org.openhab.binding.sensorcommunity.internal.mock.PMHandlerExtension;
+import org.openhab.binding.sensorcommunity.internal.mock.ThingMock;
+import org.openhab.binding.sensorcommunity.internal.util.FileReader;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link PMHandlerTest} Test Particualte Matter Handler - Config and updates
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class PMHandlerTest {
+    private Logger logger = LoggerFactory.getLogger(PMHandlerTest.class);
+
+    @Test
+    public void testValidConfigStatus() {
+        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();
+        logger.info("LC status: {}", pmHandler.getLifecycleStatus());
+        int retryCount = 0; // Test shall fail after max 10 seconds
+        while (pmHandler.getLifecycleStatus() != LifecycleStatus.RUNNING && retryCount < 20) {
+            try {
+                logger.info("LC running not reached - wait");
+                Thread.sleep(500);
+                retryCount++;
+            } catch (InterruptedException e) {
+                // nothing to do
+            }
+        }
+        /*
+         * 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.EXTERNAL_SENSOR_OK, pmHandler.getConfigStatus(), "Handler Configuration status");
+    }
+
+    @Test
+    public void testInvalidConfigStatus() {
+        ThingMock t = new ThingMock();
+
+        HashMap<String, Object> properties = new HashMap<String, Object>();
+        // String sensorid taken from thing-types.xml
+        properties.put("sensorid", -1);
+        t.setConfiguration(properties);
+
+        PMHandlerExtension pmHandler = new PMHandlerExtension(t);
+        pmHandler.initialize();
+        logger.info("LC status: {}", pmHandler.getLifecycleStatus());
+        int retryCount = 0; // Test shall fail after max 10 seconds
+        while (pmHandler.getLifecycleStatus() != LifecycleStatus.RUNNING && retryCount < 20) {
+            try {
+                logger.info("LC running not reached - wait");
+                Thread.sleep(500);
+                retryCount++;
+            } catch (InterruptedException e) {
+                // nothing to do
+            }
+        }
+        /*
+         * Test if config status is 3 = CONFIG_SENSOR_NUMBER for invalid configuration with non-number sensorid. Take
+         * real int for comparison instead of BaseHandler constants - in case of change test needs to be adapted
+         */
+        assertEquals(ConfigStatus.SENSOR_ID_NEGATIVE, pmHandler.getConfigStatus(), "Handler Configuration status");
+    }
+
+    @Test
+    public void testValidUpdate() {
+        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/pm-result.json");
+        if (pmJson != null) {
+            UpdateStatus result = pmHandler.updateChannels(pmJson);
+            assertEquals(UpdateStatus.OK, result, "Valid update");
+            assertEquals(QuantityType.valueOf(2.9, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM25Cache(), "PM25");
+            assertEquals(QuantityType.valueOf(5.2, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM100Cache(), "PM100");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testInvalidUpdate() {
+        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);
+        String pmJson = FileReader.readFileInString("src/test/resources/noise-result.json");
+        if (pmJson != null) {
+            UpdateStatus result = pmHandler.updateChannels(pmJson);
+            assertEquals(UpdateStatus.VALUE_ERROR, result, "Valid update");
+            assertEquals(QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM25Cache(),
+                    "Values undefined");
+            assertEquals(QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE), pmHandler.getPM100Cache(),
+                    "Values undefined");
+        } else {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testEmptyUpdate() {
+        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);
+        UpdateStatus result = pmHandler.updateChannels("[]");
+        assertEquals(UpdateStatus.VALUE_EMPTY, result, "Valid update");
+    }
+
+    @Test
+    public void testNullUpdate() {
+        ThingMock t = new ThingMock();
+
+        HashMap<String, Object> properties = new HashMap<String, Object>();
+        // String sensorid taken from thing-types.xml
+        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.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ConditionHandlerExtension.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ConditionHandlerExtension.java
new file mode 100644 (file)
index 0000000..be245dd
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.mock;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.handler.ConditionHandler;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.types.State;
+
+/**
+ * The {@link NoiseHandlerExtension} Test Noise Handler Extension with additonal state queries
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class ConditionHandlerExtension extends ConditionHandler {
+
+    public ConditionHandlerExtension(Thing thing) {
+        super(thing);
+    }
+
+    public ConfigStatus getConfigStatus() {
+        return configStatus;
+    }
+
+    public UpdateStatus getUpdateStatus() {
+        return lastUpdateStatus;
+    }
+
+    public @Nullable State getTemperature() {
+        return temperatureCache;
+    }
+
+    public @Nullable State getHumidity() {
+        return humidityCache;
+    }
+
+    public @Nullable State getPressure() {
+        return pressureCache;
+    }
+
+    public @Nullable State getPressureSea() {
+        return pressureSeaCache;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/NoiseHandlerExtension.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/NoiseHandlerExtension.java
new file mode 100644 (file)
index 0000000..d78e8ed
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.mock;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.handler.NoiseHandler;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.types.State;
+
+/**
+ * The {@link NoiseHandlerExtension} Test Noise Handler Extension with additonal state queries
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class NoiseHandlerExtension extends NoiseHandler {
+
+    public NoiseHandlerExtension(Thing thing) {
+        super(thing);
+    }
+
+    public ConfigStatus getConfigStatus() {
+        return configStatus;
+    }
+
+    public UpdateStatus getUpdateStatus() {
+        return lastUpdateStatus;
+    }
+
+    public @Nullable State getNoiseEQCache() {
+        return noiseEQCache;
+    }
+
+    public @Nullable State getNoiseMinCache() {
+        return noiseMinCache;
+    }
+
+    public @Nullable State getNoiseMaxCache() {
+        return noiseMaxCache;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/PMHandlerExtension.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/PMHandlerExtension.java
new file mode 100644 (file)
index 0000000..e9dc250
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.mock;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sensorcommunity.internal.handler.PMHandler;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.types.State;
+
+/**
+ * The {@link PMHandlerExtension} Test Particualte Matter Handler Extension with additonal state queries
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class PMHandlerExtension extends PMHandler {
+
+    public PMHandlerExtension(Thing thing) {
+        super(thing);
+    }
+
+    public ConfigStatus getConfigStatus() {
+        return configStatus;
+    }
+
+    public UpdateStatus getUpdateStatus() {
+        return lastUpdateStatus;
+    }
+
+    public @Nullable State getPM25Cache() {
+        return pm25Cache;
+    }
+
+    public @Nullable State getPM100Cache() {
+        return pm100Cache;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ThingMock.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ThingMock.java
new file mode 100644 (file)
index 0000000..a0a5ee9
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.mock;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.config.core.Configuration;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingStatusInfo;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.openhab.core.thing.binding.ThingHandler;
+
+/**
+ * The {@link ThingMock} Thing Mock
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class ThingMock implements Thing {
+    private Configuration config = new Configuration();
+
+    @Override
+    public @Nullable String getLabel() {
+        return null;
+    }
+
+    @Override
+    public void setLabel(@Nullable String label) {
+    }
+
+    @Override
+    public List<Channel> getChannels() {
+        return new ArrayList<Channel>();
+    }
+
+    @Override
+    public List<Channel> getChannelsOfGroup(String channelGroupId) {
+        return new ArrayList<Channel>();
+    }
+
+    @Override
+    public @Nullable Channel getChannel(String channelId) {
+        return null;
+    }
+
+    @Override
+    public @Nullable Channel getChannel(ChannelUID channelUID) {
+        return null;
+    }
+
+    @Override
+    public ThingStatus getStatus() {
+        return ThingStatus.UNKNOWN;
+    }
+
+    @Override
+    public ThingStatusInfo getStatusInfo() {
+        return new ThingStatusInfo(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "");
+    }
+
+    @Override
+    public void setStatusInfo(ThingStatusInfo status) {
+    }
+
+    @Override
+    public void setHandler(@Nullable ThingHandler thingHandler) {
+    }
+
+    @Override
+    public @Nullable ThingHandler getHandler() {
+        return null;
+    }
+
+    @Override
+    public @Nullable ThingUID getBridgeUID() {
+        return null;
+    }
+
+    @Override
+    public void setBridgeUID(@Nullable ThingUID bridgeUID) {
+    }
+
+    @Override
+    public Configuration getConfiguration() {
+        return config;
+    }
+
+    public void setConfiguration(Map<String, Object> m) {
+        config = new Configuration(m);
+    }
+
+    @Override
+    public ThingUID getUID() {
+        return new ThingUID("sensorcommunity", "test");
+    }
+
+    @Override
+    public ThingTypeUID getThingTypeUID() {
+        return new ThingTypeUID("sensorcommunity:any");
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return new HashMap<String, String>();
+    }
+
+    @Override
+    public @Nullable String setProperty(String name, @Nullable String value) {
+        return null;
+    }
+
+    @Override
+    public void setProperties(Map<String, String> properties) {
+    }
+
+    @Override
+    public @Nullable String getLocation() {
+        return null;
+    }
+
+    @Override
+    public void setLocation(@Nullable String location) {
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return false;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/DateTimeTest.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/DateTimeTest.java
new file mode 100644 (file)
index 0000000..4f23af3
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeParseException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sensorcommunity.internal.utils.DateTimeUtils;
+
+/**
+ * The {@link DateTimeTest} Test DateTimeFormatter provided in utils package
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class DateTimeTest {
+
+    @Test
+    public void testJSonTime() {
+        String jsonDateString = "2020-08-14 14:53:21";
+        try {
+            LocalDateTime dt = LocalDateTime.from(DateTimeUtils.DTF.parse(jsonDateString));
+            assertEquals(14, dt.getDayOfMonth(), "Day");
+            assertEquals(8, dt.getMonthValue(), "Month");
+            assertEquals(2020, dt.getYear(), "Year");
+
+            String s = dt.format(DateTimeUtils.DTF);
+            assertEquals(jsonDateString, s, "String");
+        } catch (DateTimeParseException e) {
+            assertFalse(true);
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/FileReader.java b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/FileReader.java
new file mode 100644 (file)
index 0000000..35d2592
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010-2023 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.sensorcommunity.internal.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link FileReader} Helper Util to read test resource files
+ *
+ * @author Bernd Weymann - Initial contribution
+ */
+@NonNullByDefault
+public class FileReader {
+
+    public static @Nullable String readFileInString(String filename) {
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "CP1252"));) {
+            StringBuffer buf = new StringBuffer();
+            String sCurrentLine;
+
+            while ((sCurrentLine = br.readLine()) != null) {
+                buf.append(sCurrentLine);
+            }
+            return buf.toString();
+        } catch (IOException e) {
+            // fail if file cannot be read
+            assertTrue(false);
+        }
+        return null;
+    }
+}
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure-flipped-values.json b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure-flipped-values.json
new file mode 100644 (file)
index 0000000..882456f
--- /dev/null
@@ -0,0 +1,73 @@
+[
+       {
+               "id": 731117559,
+               "sensordatavalues": [
+                       {
+                               "id": 1573660194,
+                               "value_type": "temperature",
+                               "value": "22.70"
+                       },
+                       {
+                               "id": 1573660195,
+                               "value_type": "humidity",
+                               "value": "61.00"
+                       }
+               ],
+               "timestamp": "2020-06-09 06:40:34",
+               "sampling_rate": null,
+               "location": {
+                       "id": 11447,
+                       "country": "DE",
+                       "altitude": "151.5",
+                       "latitude": "50.562",
+                       "longitude": "8.504",
+                       "indoor": 0,
+                       "exact_location": 0
+               },
+               "sensor": {
+                       "id": 22562,
+                       "pin": "7",
+                       "sensor_type": {
+                               "id": 9,
+                               "manufacturer": "various",
+                               "name": "DHT22"
+                       }
+               }
+       },
+       {
+               "id": 731094694,
+               "sensordatavalues": [
+                       {
+                               "id": 1573610869,
+                               "value_type": "temperature",
+                               "value": "22.50"
+                       },
+                       {
+                               "id": 1573610870,
+                               "value_type": "humidity",
+                               "value": "62.00"
+                       }
+               ],
+               "timestamp": "2020-06-09 06:38:08",
+               "sampling_ra
+               te": null,
+               "location": {
+                       "id": 11447,
+                       "country": "DE",
+                       "altitude": "151.5",
+                       "latitude": "50.562",
+                       "longitude": "8.504",
+                       "indoor": 0,
+                       "exact_location": 0
+               },
+               "sensor": {
+                       "id": 22562,
+                       "pin": "7",
+                       "sensor_type": {
+                               "id": 9,
+                               "manufacturer": "various",
+                               "name": "DHT22"
+                       }
+               }
+       }
+]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure.json b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure.json
new file mode 100644 (file)
index 0000000..7c400eb
--- /dev/null
@@ -0,0 +1,72 @@
+[
+       {
+               "id": 731094694,
+               "sensordatavalues": [
+                       {
+                               "id": 1573610869,
+                               "value_type": "temperature",
+                               "value": "22.50"
+                       },
+                       {
+                               "id": 1573610870,
+                               "value_type": "humidity",
+                               "value": "62.00"
+                       }
+               ],
+               "timestamp": "2020-06-09 06:38:08",
+               "sampling_rate": null,
+               "location": {
+                       "id": 11447,
+                       "country": "DE",
+                       "altitude": "151.5",
+                       "latitude": "50.562",
+                       "longitude": "8.504",
+                       "indoor": 0,
+                       "exact_location": 0
+               },
+               "sensor": {
+                       "id": 22562,
+                       "pin": "7",
+                       "sensor_type": {
+                               "id": 9,
+                               "manufacturer": "various",
+                               "name": "DHT22"
+                       }
+               }
+       },
+       {
+               "id": 731117559,
+               "sensordatavalues": [
+                       {
+                               "id": 1573660194,
+                               "value_type": "temperature",
+                               "value": "22.70"
+                       },
+                       {
+                               "id": 1573660195,
+                               "value_type": "humidity",
+                               "value": "61.00"
+                       }
+               ],
+               "timestamp": "2020-06-09 06:40:34",
+               "sampling_rate": null,
+               "location": {
+                       "id": 11447,
+                       "country": "DE",
+                       "altitude": "151.5",
+                       "latitude": "50.562",
+                       "longitude": "8.504",
+                       "indoor": 0,
+                       "exact_location": 0
+               },
+               "sensor": {
+                       "id": 22562,
+                       "pin": "7",
+                       "sensor_type": {
+                               "id": 9,
+                               "manufacturer": "various",
+                               "name": "DHT22"
+                       }
+               }
+       }
+]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-plus-pressure.json b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-plus-pressure.json
new file mode 100644 (file)
index 0000000..4d7a30b
--- /dev/null
@@ -0,0 +1,90 @@
+[
+       {
+               "id": 1038856661,
+               "sensor": {
+                       "id": 28843,
+                       "sensor_type": {
+                               "id": 17,
+                               "manufacturer": "Bosch",
+                               "name": "BME280"
+                       },
+                       "pin": "11"
+               },
+               "timestamp": "2020-07-03 09:39:46",
+               "sampling_rate": null,
+               "location": {
+                       "id": 15975,
+                       "altitude": "151.2",
+                       "longitude": "8.49543571448",
+                       "exact_location": 1,
+                       "latitude": "50.55591005174",
+                       "indoor": 0,
+                       "country": "DE"
+               },
+               "sensordatavalues": [
+                       {
+                               "id": 2237770681,
+                               "value_type": "temperature",
+                               "value": "21.52"
+                       },
+                       {
+                               "id": 2237770683,
+                               "value_type": "pressure",
+                               "value": "100199.97"
+                       },
+                       {
+                               "id": 2237770684,
+                               "value_type": "humidity",
+                               "value": "58.51"
+                       },
+                       {
+                               "value_type": "pressure_at_sealevel",
+                               "value": 101968.66
+                       }
+               ]
+       },
+       {
+               "id": 1038834126,
+               "sensor": {
+                       "id": 28843,
+                       "sensor_type": {
+                               "id": 17,
+                               "manufacturer": "Bosch",
+                               "name": "BME280"
+                       },
+                       "pin": "11"
+               },
+               "timestamp": "2020-07-03 09:37:21",
+               "sampling_rate": null,
+               "location": {
+                       "id": 15975,
+                       "altitude": "151.2",
+                       "longitude": "8.49543571448",
+                       "exact_location": 1,
+                       "latitude": "50.55591005174",
+                       "indoor": 0,
+                       "country": "DE"
+               },
+               "sensordatavalues": [
+                       {
+                               "id": 2237722004,
+                               "value_type": "temperature",
+                               "value": "21.45"
+                       },
+                       {
+                               "id": 2237722008,
+                               "value_type": "pressure",
+                               "value": "100205.09"
+                       },
+                       {
+                               "id": 2237722009,
+                               "value_type": "humidity",
+                               "value": "58.79"
+                       },
+                       {
+                               "value_type": "pressure_at_sealevel",
+                               "value": 101974.29
+                       }
+               ]
+       }
+]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/internal-data.json b/bundles/org.openhab.binding.sensorcommunity/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
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/noise-result.json b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/noise-result.json
new file mode 100644 (file)
index 0000000..2f9aa7a
--- /dev/null
@@ -0,0 +1,82 @@
+[
+       {
+               "timestamp": "2020-06-11 09:39:51",
+               "sensordatavalues": [
+                       {
+                               "value": "50.95",
+                               "id": 1629930130,
+                               "value_type": "noise_LAeq"
+                       },
+                       {
+                               "value": "47.20",
+                               "id": 1629930131,
+                               "value_type": "noise_LA_min"
+                       },
+                       {
+                               "value": "56.95",
+                               "id": 1629930132,
+                               "value_type": "noise_LA_max"
+                       }
+               ],
+               "sampling_rate": null,
+               "location": {
+                       "exact_location": 1,
+                       "latitude": "50.88827895000",
+                       "country": "DE",
+                       "altitude": "294.9",
+                       "indoor": 0,
+                       "longitude": "7.87451286686",
+                       "id": 25429
+               },
+               "id": 757217220,
+               "sensor": {
+                       "sensor_type": {
+                               "id": 29,
+                               "manufacturer": "Sensor.Community",
+                               "name": "Laerm"
+                       },
+                       "pin": "15",
+                       "id": 39745
+               }
+       },
+       {
+               "timestamp": "2020-06-11 09:37:25",
+               "sensordatavalues": [
+                       {
+                               "value": "52.02",
+                               "id": 1629881984,
+                               "value_type": "noise_LAeq"
+                       },
+                       {
+                               "value": "45.98",
+                               "id": 1629881986,
+                               "value_type": "noise_LA_min"
+                       },
+                       {
+                               "value": "69.28",
+                               "id": 1629881987,
+                               "value_type": "noise_LA_max"
+                       }
+               ],
+               "sampling_rate": null,
+               "location": {
+                       "exact_location": 1,
+                       "latitude": "50.88827895000",
+                       "country": "DE",
+                       "altitude": "294.9",
+                       "indoor": 0,
+                       "longitude": "7.87451286686",
+                       "id": 25429
+               },
+               "id": 757194885,
+               "sensor": {
+                       "sensor_type": {
+                               "id": 29,
+                               "manufacturer": "Sensor.Community",
+                               "name": "Laerm"
+                       },
+                       "pin": "15",
+                       "id": 39745
+               }
+       }
+]
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.sensorcommunity/src/test/resources/pm-result.json b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/pm-result.json
new file mode 100644 (file)
index 0000000..73e5768
--- /dev/null
@@ -0,0 +1,72 @@
+[
+       {
+               "timestamp": "2020-06-11 09:40:41",
+               "sensordatavalues": [
+                       {
+                               "value": "5.15",
+                               "id": 1629948185,
+                               "value_type": "P1"
+                       },
+                       {
+                               "value": "2.87",
+                               "id": 1629948191,
+                               "value_type": "P2"
+                       }
+               ],
+               "sampling_rate": null,
+               "location": {
+                       "exact_location": 1,
+                       "latitude": "50.55591005174",
+                       "country": "DE",
+                       "altitude": "151.2",
+                       "indoor": 0,
+                       "longitude": "8.49543571448",
+                       "id": 15975
+               },
+               "id": 757225623,
+               "sensor": {
+                       "sensor_type": {
+                               "id": 14,
+                               "manufacturer": "Nova Fitness",
+                               "name": "SDS011"
+                       },
+                       "pin": "1",
+                       "id": 28842
+               }
+       },
+       {
+               "timestamp": "2020-06-11 09:38:16",
+               "sensordatavalues": [
+                       {
+                               "value": "2.20",
+                               "id": 1629900061,
+                               "value_type": "P1"
+                       },
+                       {
+                               "value": "2.00",
+                               "id": 1629900063,
+                               "value_type": "P2"
+                       }
+               ],
+               "sampling_rate": null,
+               "location": {
+                       "exact_location": 1,
+                       "latitude": "50.55591005174",
+                       "country": "DE",
+                       "altitude": "151.2",
+                       "indoor": 0,
+                       "longitude": "8.49543571448",
+                       "id": 15975
+               },
+               "id": 757203291,
+               "sensor": {
+                       "sensor_type": {
+                               "id": 14,
+                               "manufacturer": "Nova Fitness",
+                               "name": "SDS011"
+                       },
+                       "pin": "1",
+                       "id": 28842
+               }
+       }
+]
\ No newline at end of file
index 6ee1c3186b7daf469a2f78d74d63da51e64b5d9a..9b841e9ed459bd0d67ac3e54e46af6e34198b07a 100644 (file)
     <module>org.openhab.binding.livisismarthome</module>
     <module>org.openhab.binding.logreader</module>
     <module>org.openhab.binding.loxone</module>
-    <module>org.openhab.binding.luftdateninfo</module>
     <module>org.openhab.binding.lutron</module>
     <module>org.openhab.binding.luxom</module>
     <module>org.openhab.binding.luxtronikheatpump</module>
     <module>org.openhab.binding.seneye</module>
     <module>org.openhab.binding.sensebox</module>
     <module>org.openhab.binding.sensibo</module>
+    <module>org.openhab.binding.sensorcommunity</module>
     <module>org.openhab.binding.serial</module>
     <module>org.openhab.binding.serialbutton</module>
     <module>org.openhab.binding.shelly</module>