Skip to content

Commit

Permalink
[pegelonline] Initial contribution (openhab#16831)
Browse files Browse the repository at this point in the history
* initial version

Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
  • Loading branch information
weymann authored Jun 15, 2024
1 parent 5e15726 commit 7fa43ea
Show file tree
Hide file tree
Showing 26 changed files with 11,055 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
/bundles/org.openhab.binding.orvibo/ @tavalin
/bundles/org.openhab.binding.panasonicbdp/ @mlobstein
/bundles/org.openhab.binding.paradoxalarm/ @theater
/bundles/org.openhab.binding.pegelonline/ @weymann
/bundles/org.openhab.binding.pentair/ @jsjames
/bundles/org.openhab.binding.phc/ @gnlpfjh
/bundles/org.openhab.binding.pilight/ @stefanroellin @niklasdoerfler
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,11 @@
<artifactId>org.openhab.binding.paradoxalarm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.pegelonline</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.pentair</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.pegelonline/NOTICE
Original file line number Diff line number Diff line change
@@ -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
122 changes: 122 additions & 0 deletions bundles/org.openhab.binding.pegelonline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# PegelOnline Binding

Binding to observe water level from german rivers.
Data is provided by german **Water-Route and Shipping Agency** [WSV](https://www.pegelonline.wsv.de/).
Goal is to monitor actual water levels from rivers nearby your home.
In case of changing water levels the corresponding warning level is lowered or raised.

## Supported Things

| Label | Description | ID |
|---------------------|---------------------------------------------------------------------------------|---------|
| Measurement Station | Station providing water level measurements | station |


## Discovery

In case your home location coordinates are set the discovery will recognize all measurement stations within a radius of 50 km.
Found Things are added in your Inbox.


## Thing Configuration

Thing configuration contains 3 sections

* [Station selection](station_selection)
* [Warning Levels of selected station](warning_levels)
* [Refresh rate](configuration_parameters)

### Station selection

Stations can be selected with an Universally Unique Identifier (uuid).
It's automatically added by the Discovery.
Configure a station manually using [list of all available stations](https://pegelonline.wsv.de/gast/pegeltabelle) or [stations.json](https://www.pegelonline.wsv.de/webservices/rest-api/v2/stations.json) and choose the uuid of your desired measurement station.

### Warning Levels

<img align="right" src="./doc/Marburg.png" width="450" height="500"/>

Each station has specific warning levels

* Warning Levels 1 (*lowest*) to 3 (*highest*)
* Flooding Levels

Unfortunately these levels cannot be queried automatically.
Please select your [federal state](https://www.hochwasserzentralen.de/) and check if which levels they provide.
The picture shows the levels of [measurement station Marburg of federal state Hesse](https://www.hlnug.de/static/pegel/wiskiweb2/stations/25830056/station.html?v=20210802152952)

If you cannot evaluate warning or flooding levels leave the parameter empty.

### Configuration parameters

| configuration | content | unit | description | required | default |
|------------------|-----------|------|---------------------------|----------|---------|
| uuid | text | - | Unique Station Identifier | X | N/A |
| warningLevel1 | integer | cm | Warning Level 1 | | N/A |
| warningLevel2 | integer | cm | Warning Level 2 | | N/A |
| warningLevel3 | integer | cm | Warning Level 3 | | N/A |
| hq10 | integer | cm | Decade Flooding | | N/A |
| hq100 | integer | cm | Century Flooding | | N/A |
| hqExtreme | integer | cm | Extreme Flooding | | N/A |
| refreshInterval | integer | min | Refresh Interval | X | 15 |

## Channels


| channel id | type | description |
|----------------------|----------------------|--------------------------------|
| timestamp | DateTime | Last Measurement |
| level | Number:Length | Water Level |
| trend | Number | Water Level Trend |
| warning | Number | Current Warning |

### Trend

Possible values:

* 1 : Rising
* 0 : Steady
* -1 : Lowering

### Warning

Current warning according to configuration

* 0 : No Warning
* 1 : Warning level 1
* 2 : Warning Level 2
* 3 : Warning Level 3
* 4 : Decade Flooding
* 5 : Century Flooding
* 6 : Extreme Flooding

## Full Example

### Things

```java
Thing pegelonline:station:giessen "Measurement Station Giessen" [
uuid="4b386a6a-996e-4a4a-a440-15d6b40226d4",
refreshInterval=15,
warningLevel1=550,
warningLevel2=600,
warningLevel3=650,
hq10=732,
hq100=786
]
```

### Items

```java
DateTime Lahn_Giessen_Timestamp "Measurement timestamp Lahn Giessen" {channel="pegelonline:station:giessen:timestamp" }
Number:Length Lahn_Giessen_Level "Water Level Lahn Giessen]" {channel="pegelonline:station:giessen:level" }
Number Lahn_Giessen_Trend "Water Level Trend Lahn Giessen" {channel="pegelonline:station:giessen:trend"}
Number Lahn_Giessen_Warning "Warning Level Lahn Giessen" {channel="pegelonline:station:giessen:warning"}
```


## Links

[PegelOnline API Documentation](https://www.pegelonline.wsv.de/webservice/dokuRestapi#caching)

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.pegelonline/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>4.2.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.pegelonline</artifactId>

<name>openHAB Add-ons :: Bundles :: PegelOnline Binding</name>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.pegelonline-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-pegelonline" description="PegelOnline Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.pegelonline/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2010-2024 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.pegelonline.internal;

import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.library.types.PointType;
import org.openhab.core.thing.ThingTypeUID;

import com.google.gson.Gson;

/**
* The {@link PegelOnlineBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Bernd Weymann - Initial contribution
*/
@NonNullByDefault
public class PegelOnlineBindingConstants {

private static final String BINDING_ID = "pegelonline";

// List of all Thing Type UIDs
public static final ThingTypeUID STATION_THING = new ThingTypeUID(BINDING_ID, "station");
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(STATION_THING);

// List of all Channel ids
public static final String TIMESTAMP_CHANNEL = "timestamp";
public static final String LEVEL_CHANNEL = "level";
public static final String TREND_CHANNEL = "trend";
public static final String WARNING_CHANNEL = "warning";

public static final int NO_WARNING = 0;
public static final int WARN_LEVEL_1 = 1;
public static final int WARN_LEVEL_2 = 2;
public static final int WARN_LEVEL_3 = 3;
public static final int HQ10 = 4;
public static final int HQ100 = 5;
public static final int HQ_EXTREME = 6;

public static final Gson GSON = new Gson();

public static final String STATIONS_URI = "https://www.pegelonline.wsv.de/webservices/rest-api/v2/stations";
public static final double DISCOVERY_RADIUS = 50;
public static final PointType UNDEF_LOCATION = PointType.valueOf("-1,-1");

public static final String SPACE = " ";
public static final String UNDERLINE = "_";
public static final String HYPHEN = " - ";
public static final String EMPTY = "";
public static final String UNKNOWN = "Unknown";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2010-2024 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.pegelonline.internal;

import static org.openhab.binding.pegelonline.internal.PegelOnlineBindingConstants.STATION_THING;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.pegelonline.internal.handler.PegelOnlineHandler;
import org.openhab.core.i18n.LocationProvider;
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;

/**
* The {@link PegelOnlineHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Bernd Weymann - Initial contribution
*/
@NonNullByDefault
@Component(configurationPid = "binding.pegelonline", service = ThingHandlerFactory.class)
public class PegelOnlineHandlerFactory extends BaseThingHandlerFactory {
private final HttpClientFactory httpClientFactory;

@Activate
public PegelOnlineHandlerFactory(final @Reference HttpClientFactory hcf, final @Reference LocationProvider lp) {
httpClientFactory = hcf;
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return PegelOnlineBindingConstants.SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (STATION_THING.equals(thingTypeUID)) {
return new PegelOnlineHandler(thing, httpClientFactory.getCommonHttpClient());
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2010-2024 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.pegelonline.internal.config;

import static org.openhab.binding.pegelonline.internal.PegelOnlineBindingConstants.*;

import java.util.Map.Entry;
import java.util.TreeMap;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link PegelOnlineConfiguration} class contains fields mapping thing configuration parameters.
*
* @author Bernd Weymann - Initial contribution
*/
@NonNullByDefault
public class PegelOnlineConfiguration {
public String uuid = UNKNOWN;
public int warningLevel1 = Integer.MAX_VALUE;
public int warningLevel2 = Integer.MAX_VALUE;
public int warningLevel3 = Integer.MAX_VALUE;
public int hq10 = Integer.MAX_VALUE;
public int hq100 = Integer.MAX_VALUE;
public int hqExtreme = Integer.MAX_VALUE;
public int refreshInterval = 15;

public boolean uuidCheck() {
// https://stackoverflow.com/questions/20041051/how-to-judge-a-string-is-uuid-type
return uuid.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
}

/**
* Check if configured warning levels are in ascending order
*
* @return true if ascending, false otherwise
*/
public boolean warningCheck() {
TreeMap<Integer, Integer> warnMap = this.getWarnings();
Entry<Integer, Integer> currentEntry = warnMap.firstEntry();
Entry<Integer, Integer> nextEntry = warnMap.higherEntry(currentEntry.getKey());
while (nextEntry != null) {
// ignore non configured values
if (nextEntry.getKey() != Integer.MAX_VALUE) {
if (nextEntry.getValue() < currentEntry.getValue()) {
return false;
}
}
currentEntry = nextEntry;
nextEntry = warnMap.higherEntry(currentEntry.getKey());
}
return true;
}

/**
* Calculate sorted map with level height and warning level based on configuration
*
* @return TreeMap with keys containing level height and values containing warning level
*/
public TreeMap<Integer, Integer> getWarnings() {
TreeMap<Integer, Integer> warnMap = new TreeMap<>();
warnMap.put(0, NO_WARNING);
warnMap.put(warningLevel1, WARN_LEVEL_1);
warnMap.put(warningLevel2, WARN_LEVEL_2);
warnMap.put(warningLevel3, WARN_LEVEL_3);
warnMap.put(hq10, HQ10);
warnMap.put(hq100, HQ100);
warnMap.put(hqExtreme, HQ_EXTREME);
return warnMap;
}
}
Loading

0 comments on commit 7fa43ea

Please sign in to comment.