From: Holger Friedrich Date: Mon, 22 May 2023 05:57:23 +0000 (+0200) Subject: [luftdateninfo][sensorcommunity] Rename binding to Sensor.Community (#15012) X-Git-Url: https://git.basschouten.com/?a=commitdiff_plain;h=d8376aa6d05dd82c8d6c2fefc65e4fba4e4037f2;p=openhab-addons.git [luftdateninfo][sensorcommunity] Rename binding to Sensor.Community (#15012) * [luftdateninfo][sensorcommunity] Rename binding to match the new name Sensor.Community Signed-off-by: Holger Friedrich --- diff --git a/CODEOWNERS b/CODEOWNERS index 210ce9a624..8339cf8b62 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -180,7 +180,6 @@ /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 @@ -300,6 +299,7 @@ /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 diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml index 420d5cd444..6e84ed35d3 100644 --- a/bom/openhab-addons/pom.xml +++ b/bom/openhab-addons/pom.xml @@ -896,11 +896,6 @@ org.openhab.binding.loxone ${project.version} - - org.openhab.addons.bundles - org.openhab.binding.luftdateninfo - ${project.version} - org.openhab.addons.bundles org.openhab.binding.lutron @@ -1491,6 +1486,11 @@ org.openhab.binding.sensibo ${project.version} + + org.openhab.addons.bundles + org.openhab.binding.sensorcommunity + ${project.version} + org.openhab.addons.bundles org.openhab.binding.serial diff --git a/bundles/org.openhab.binding.luftdateninfo/NOTICE b/bundles/org.openhab.binding.luftdateninfo/NOTICE deleted file mode 100644 index 38d625e349..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/NOTICE +++ /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 index 9cb7bceb98..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/README.md +++ /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 | - -### 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 index faa378dfbc..0000000000 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 index ccf4e6f1fd..0000000000 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 index 660668eba4..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 4.0.0 - - - org.openhab.addons.bundles - org.openhab.addons.reactor.bundles - 4.0.0-SNAPSHOT - - - org.openhab.binding.luftdateninfo - - openHAB Add-ons :: Bundles :: LuftdatenInfo Binding - - 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 index 0c844e72fc..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/feature/feature.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features - - - openhab-runtime-base - mvn:org.openhab.addons.bundles/org.openhab.binding.luftdateninfo/${project.version} - - 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 index d594b426e4..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoBindingConstants.java +++ /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 index d3cc4eba15..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoConfiguration.java +++ /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 index 42ff36adca..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/LuftdatenInfoHandlerFactory.java +++ /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 index ddd03d1145..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Location.java +++ /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 index a8036a878e..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/Sensor.java +++ /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 index 4c340d8ba2..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorData.java +++ /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 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 getSensorDataValues() { - return sensorDataValues; - } - - public void setSensorDataValues(List 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 index 9a9ec3577b..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorDataValue.java +++ /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 index 811eb19da9..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/dto/SensorType.java +++ /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 index 9c6aae3e37..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/BaseSensorHandler.java +++ /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 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 index 2c9e376db9..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/ConditionHandler.java +++ /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 temperatureCache = QuantityType.valueOf(-1, SIUnits.CELSIUS); - protected QuantityType humidityCache = QuantityType.valueOf(-1, Units.PERCENT); - protected QuantityType pressureCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)); - protected QuantityType pressureSeaCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)); - - public ConditionHandler(Thing thing) { - super(thing); - } - - @Override - public UpdateStatus updateChannels(@Nullable String json) { - if (json != null) { - List 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 index 99c30dc4a1..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/HTTPHandler.java +++ /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 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 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 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 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 index 509631db63..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/NoiseHandler.java +++ /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 noiseEQCache = QuantityType.valueOf(-1, Units.DECIBEL); - protected QuantityType noiseMinCache = QuantityType.valueOf(-1, Units.DECIBEL); - protected QuantityType noiseMaxCache = QuantityType.valueOf(-1, Units.DECIBEL); - - public NoiseHandler(Thing thing) { - super(thing); - } - - @Override - public UpdateStatus updateChannels(@Nullable String json) { - if (json != null) { - List 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 index 7ee0aa3838..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/handler/PMHandler.java +++ /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 pm25Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE); - protected QuantityType 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 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 index 71181ac049..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/Constants.java +++ /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 index f366941686..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/DateTimeUtils.java +++ /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 index 50a628dfd8..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/java/org/openhab/binding/luftdateninfo/internal/utils/NumberUtils.java +++ /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 index 37184958bb..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/addon/addon.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - binding - LuftdatenInfo Binding - Binding to integrate DIY Sensors from luftdaten.info Sensor Community - hybrid - - 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 index de36138221..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo.properties +++ /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 index 1ba9feb21e..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/i18n/luftdateninfo_de.properties +++ /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 index 001a2c1cb9..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/main/resources/OH-INF/thing/thing-types.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - Sensor to measure Particulate Matter (PM) - - - - - - - - - network-address - - Local IP address of your personal owned sensor - - - - Sensor ID from https://deutschland.maps.sensor.community/ - - - - - - - Sensor to measure Temperature and Humidity conditions - - - - - - - - - - - network-address - - Local IP address of your personal owned sensor - - - - Sensor ID from https://deutschland.maps.sensor.community/ - - - - - - - Sensor to measure noise on location - - - - - - - - - - network-address - - Local IP address of your personal owned sensor - - - - Sensor ID from https://deutschland.maps.sensor.community/ - - - - - - Number:Density - - - - - Number:Density - - - - - Number:Temperature - - Temperature from the selected Sensor ID - - - - Number:Dimensionless - - Humidity from the selected Sensor ID - - - - Number:Pressure - - Atmospheric Pressure from the selected Sensor ID - - - - Number:Pressure - - Atmospheric Pressure at sea level from the selected Sensor ID - - - - Number:Dimensionless - - Average noise level from the selected Sensor ID - - - - Number:Dimensionless - - Minimum noise level (last 2.5 minutes) from the selected Sensor ID - - - - Number:Dimensionless - - Maximum noise level (last 2.5 minutes) from the selected Sensor ID - - - 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 index eb9f52f0d7..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/ConditionHandlerTest.java +++ /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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 index 2e203d6198..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/DTOTest.java +++ /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 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 index f04248be79..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerEvalTest.java +++ /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 conditions; - private @Nullable List particulate; - private @Nullable List 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 index 8d3a7bacb3..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/HTTPHandlerValueTest.java +++ /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 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 index 22428b1db0..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NoiseHandlerTest.java +++ /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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 index e2206e91d6..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/NumberTest.java +++ /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 index ae8026a83e..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/PMHandlerTest.java +++ /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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 properties = new HashMap(); - // 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 index e7431f014c..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ConditionHandlerExtension.java +++ /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 index 99f306d34b..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/NoiseHandlerExtension.java +++ /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 index b04fd90ca6..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/PMHandlerExtension.java +++ /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 index 060ef220a2..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/mock/ThingMock.java +++ /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 getChannels() { - return new ArrayList(); - } - - @Override - public List getChannelsOfGroup(String channelGroupId) { - return new ArrayList(); - } - - @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 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 getProperties() { - return new HashMap(); - } - - @Override - public @Nullable String setProperty(String name, @Nullable String value) { - return null; - } - - @Override - public void setProperties(Map 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 index 13d2548351..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/DateTimeTest.java +++ /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 index 7898a4b158..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/java/org/openhab/binding/luftdateninfo/internal/util/FileReader.java +++ /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 index 882456f1f3..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure-flipped-values.json +++ /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 index 7c400ebaad..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-no-pressure.json +++ /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 index 4d7a30b2ce..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/condition-result-plus-pressure.json +++ /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 index 04d75b42dc..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/internal-data.json +++ /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 index 053f7bd398..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/noise-result.json +++ /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 index 73e5768f99..0000000000 --- a/bundles/org.openhab.binding.luftdateninfo/src/test/resources/pm-result.json +++ /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 index 0000000000..38d625e349 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/NOTICE @@ -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 index 0000000000..7e93d7670b --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/README.md @@ -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 | + +### 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 index 0000000000..faa378dfbc 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 index 0000000000..ccf4e6f1fd 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 index 0000000000..489668d762 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + org.openhab.addons.bundles + org.openhab.addons.reactor.bundles + 4.0.0-SNAPSHOT + + + org.openhab.binding.sensorcommunity + + openHAB Add-ons :: Bundles :: Sensor.Community Binding + + 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 index 0000000000..7e84b4acee --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/feature/feature.xml @@ -0,0 +1,9 @@ + + + mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features + + + openhab-runtime-base + mvn:org.openhab.addons.bundles/org.openhab.binding.sensorcommunity/${project.version} + + 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 index 0000000000..a566efac07 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityBindingConstants.java @@ -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 index 0000000000..e49c932de8 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityConfiguration.java @@ -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 index 0000000000..ae8a8db33d --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/SensorCommunityHandlerFactory.java @@ -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 index 0000000000..7b24edb566 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Location.java @@ -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 index 0000000000..fe96f6a584 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/Sensor.java @@ -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 index 0000000000..9e468cc193 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorData.java @@ -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 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 getSensorDataValues() { + return sensorDataValues; + } + + public void setSensorDataValues(List 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 index 0000000000..cf50101b77 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorDataValue.java @@ -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 index 0000000000..2e00ee40e5 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/dto/SensorType.java @@ -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 index 0000000000..58b462f3d8 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/BaseSensorHandler.java @@ -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 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 index 0000000000..e114c1ee5c --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/ConditionHandler.java @@ -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 temperatureCache = QuantityType.valueOf(-1, SIUnits.CELSIUS); + protected QuantityType humidityCache = QuantityType.valueOf(-1, Units.PERCENT); + protected QuantityType pressureCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)); + protected QuantityType pressureSeaCache = QuantityType.valueOf(-1, HECTO(SIUnits.PASCAL)); + + public ConditionHandler(Thing thing) { + super(thing); + } + + @Override + public UpdateStatus updateChannels(@Nullable String json) { + if (json != null) { + List 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 index 0000000000..75ecf8ff44 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/HTTPHandler.java @@ -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 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 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 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 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 index 0000000000..1eb882bcab --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/NoiseHandler.java @@ -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 noiseEQCache = QuantityType.valueOf(-1, Units.DECIBEL); + protected QuantityType noiseMinCache = QuantityType.valueOf(-1, Units.DECIBEL); + protected QuantityType noiseMaxCache = QuantityType.valueOf(-1, Units.DECIBEL); + + public NoiseHandler(Thing thing) { + super(thing); + } + + @Override + public UpdateStatus updateChannels(@Nullable String json) { + if (json != null) { + List 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 index 0000000000..ff58d9761d --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/handler/PMHandler.java @@ -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 pm25Cache = QuantityType.valueOf(-1, Units.MICROGRAM_PER_CUBICMETRE); + protected QuantityType 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 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 index 0000000000..69ed677d19 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/Constants.java @@ -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 index 0000000000..de79e6d356 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/DateTimeUtils.java @@ -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 index 0000000000..cf8ef3bb58 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/java/org/openhab/binding/sensorcommunity/internal/utils/NumberUtils.java @@ -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 index 0000000000..b190653840 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/addon/addon.xml @@ -0,0 +1,11 @@ + + + + binding + Sensor.Community Binding + Binding to integrate DIY Sensors from Sensor.Community + hybrid + + 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 index 0000000000..cb1e4eaa35 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity.properties @@ -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 index 0000000000..b7b800f2bc --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/i18n/sensorcommunity_de.properties @@ -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 index 0000000000..89684f8b3c --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/main/resources/OH-INF/thing/thing-types.xml @@ -0,0 +1,128 @@ + + + + + + Sensor to measure Particulate Matter (PM) + + + + + + + + + network-address + + Local IP address of your personal owned sensor + + + + Sensor ID from https://deutschland.maps.sensor.community/ + + + + + + + Sensor to measure Temperature and Humidity conditions + + + + + + + + + + + network-address + + Local IP address of your personal owned sensor + + + + Sensor ID from https://deutschland.maps.sensor.community/ + + + + + + + Sensor to measure noise on location + + + + + + + + + + network-address + + Local IP address of your personal owned sensor + + + + Sensor ID from https://deutschland.maps.sensor.community/ + + + + + + Number:Density + + + + + Number:Density + + + + + Number:Temperature + + Temperature from the selected Sensor ID + + + + Number:Dimensionless + + Humidity from the selected Sensor ID + + + + Number:Pressure + + Atmospheric Pressure from the selected Sensor ID + + + + Number:Pressure + + Atmospheric Pressure at sea level from the selected Sensor ID + + + + Number:Dimensionless + + Average noise level from the selected Sensor ID + + + + Number:Dimensionless + + Minimum noise level (last 2.5 minutes) from the selected Sensor ID + + + + Number:Dimensionless + + Maximum noise level (last 2.5 minutes) from the selected Sensor ID + + + 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 index 0000000000..9df8f12147 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/ConditionHandlerTest.java @@ -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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 index 0000000000..9d9fcfbb71 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/DTOTest.java @@ -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 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 index 0000000000..6f42d6a07b --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerEvalTest.java @@ -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 conditions; + private @Nullable List particulate; + private @Nullable List 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 index 0000000000..d5a38051ff --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/HTTPHandlerValueTest.java @@ -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 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 index 0000000000..b1204af623 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NoiseHandlerTest.java @@ -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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 index 0000000000..a0fb1974e8 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/NumberTest.java @@ -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 index 0000000000..2a979e86c6 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/PMHandlerTest.java @@ -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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 properties = new HashMap(); + // 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 index 0000000000..be245dde0b --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ConditionHandlerExtension.java @@ -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 index 0000000000..d78e8ed760 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/NoiseHandlerExtension.java @@ -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 index 0000000000..e9dc250af1 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/PMHandlerExtension.java @@ -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 index 0000000000..a0a5ee901b --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/mock/ThingMock.java @@ -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 getChannels() { + return new ArrayList(); + } + + @Override + public List getChannelsOfGroup(String channelGroupId) { + return new ArrayList(); + } + + @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 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 getProperties() { + return new HashMap(); + } + + @Override + public @Nullable String setProperty(String name, @Nullable String value) { + return null; + } + + @Override + public void setProperties(Map 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 index 0000000000..4f23af308a --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/DateTimeTest.java @@ -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 index 0000000000..35d2592d54 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/java/org/openhab/binding/sensorcommunity/internal/util/FileReader.java @@ -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 index 0000000000..882456f1f3 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure-flipped-values.json @@ -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 index 0000000000..7c400ebaad --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-no-pressure.json @@ -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 index 0000000000..4d7a30b2ce --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/condition-result-plus-pressure.json @@ -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 index 0000000000..04d75b42dc --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/internal-data.json @@ -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 index 0000000000..2f9aa7a5eb --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/noise-result.json @@ -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 index 0000000000..73e5768f99 --- /dev/null +++ b/bundles/org.openhab.binding.sensorcommunity/src/test/resources/pm-result.json @@ -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 diff --git a/bundles/pom.xml b/bundles/pom.xml index 6ee1c3186b..9b841e9ed4 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -214,7 +214,6 @@ org.openhab.binding.livisismarthome org.openhab.binding.logreader org.openhab.binding.loxone - org.openhab.binding.luftdateninfo org.openhab.binding.lutron org.openhab.binding.luxom org.openhab.binding.luxtronikheatpump @@ -334,6 +333,7 @@ org.openhab.binding.seneye org.openhab.binding.sensebox org.openhab.binding.sensibo + org.openhab.binding.sensorcommunity org.openhab.binding.serial org.openhab.binding.serialbutton org.openhab.binding.shelly